DynamoDB PartiQL vs SQL: O Que Quebra
A maior fonte de confusão com o PartiQL do DynamoDB — tanto para humanos quanto para assistentes de IA — é tratá-lo como SQL relacional. Ele não é. O PartiQL é uma superfície compatível com SQL sobre as operações existentes do DynamoDB, não um motor de consulta que consegue fazer join, agrupar ou agregar. As palavras-chave familiares escondem uma máquina muito diferente por baixo.
Como o PartiQL do DynamoDB é diferente do SQL?
O PartiQL toma emprestada a sintaxe do SQL, mas não o seu motor. No DynamoDB, toda instrução mapeia para uma única operação nativa — GetItem, Query, Scan, PutItem, UpdateItem ou DeleteItem — então não existe JOIN, GROUP BY, subconsulta ou agregado. Ele se lê como SQL, mas só consegue fazer o que essas operações chave-valor já fazem.
Toda instrução PartiQL compila para uma das operações nativas do DynamoDB:
| Você escreve | O DynamoDB executa |
|---|---|
SELECT … WHERE PK = … | GetItem ou Query |
SELECT … (sem PK) | Scan (lê a tabela inteira) |
INSERT INTO … | PutItem |
UPDATE … WHERE PK=… AND SK=… | UpdateItem (um item) |
DELETE … WHERE PK=… AND SK=… | DeleteItem (um item) |
Não existe planejador que consiga ler de duas tabelas, construir um hash join ou dobrar linhas
em um COUNT. Se uma operação não mapeia para um único Get/Query/Scan/Put/Update/
Delete, o PartiQL simplesmente não consegue expressá-la. Essa é a história toda — tudo abaixo
é uma consequência desse único fato.
O mesmo mapeamento, como um fluxo — a cláusula WHERE decide se um SELECT é um
Query barato ou um Scan de tabela inteira:
Cada instrução resolve para exatamente uma operação nativa — esse mapeamento um-para-um é o motivo pelo qual o PartiQL não consegue fazer join, agrupar ou agregar.
O que é diferente — recurso por recurso
Sempre que a coluna Workbench diz Sim contra um Não do PartiQL, essa é uma lacuna que a SQL do DynoTable fecha. A Workbench materializa suas tabelas através do runtime de consulta real do DynamoDB e roda SQL real por cima — SQL dentro das regras de padrão de acesso do DynamoDB.
| Recurso | SQL padrão | DynamoDB PartiQL | DynoTable Workbench |
|---|---|---|---|
JOIN … ON … | Sim | Não | Sim — INNER / LEFT (para uma PK ou chave de partição de GSI) |
RIGHT / FULL / CROSS / comma-join | Sim | Não | Não |
| Self-join | Sim | Não | Não (ainda não) |
| Subconsultas / tabelas derivadas | Sim | Não | Não |
CTEs (WITH …) | Sim | Não | Não |
UNION / INTERSECT / EXCEPT | Sim | Não | Não |
GROUP BY / HAVING | Sim | Não | Sim |
Agregados (COUNT/SUM/AVG/MIN/MAX) | Sim | Não | Sim |
DISTINCT | Sim | Não | Sim |
CASE / CAST | Sim | Não | Sim |
| Funções de janela | Sim | Não | Não |
ORDER BY | Sim, qualquer coluna | Parcial — só chave de classificação (precisa de WHERE na chave de partição) | Sim, qualquer coluna |
LIMIT | Sim | Não inline (use o parâmetro limit da requisição) | Sim |
LIKE | Sim | Não (use contains / begins_with) | Sim |
IS NULL / IS NOT NULL | Sim | Sim (atributos ausentes são MISSING, não NULL — use IS MISSING) | Sim |
SELECT * sem uma PK | faz scan | Parcial — Scan silencioso de tabela inteira | Sim (com visibilidade de custo) |
O que quebra, e por quê
Estas são as falhas que o validador de PartiQL do DynoTable sinaliza antes de a consulta sequer chegar à rede — cada uma remonta a uma restrição real do DynamoDB.
SELECT *sem uma é umScanescondido. O PartiQL não dá erro; ele apenas lê cada item e filtra depois, que é a clássica cilada de custo Query-vs-Scan por trás da sintaxe amigável.UPDATE/DELETEprecisam da chave primária completa. Eles mapeiam para umUpdateItem/DeleteItemde item único, então oWHEREdeve fixar a chave de partição (e a chave de classificação, em uma tabela de ). Você não pode "atualizar todas as linhas onde status = 'open'" em uma instrução.- Aspas duplas são identificadores, não strings. O PartiQL do DynamoDB segue o padrão
SQL aqui:
"name"é o nome de uma coluna/tabela,'name'é um valor string. Colocar aspas duplas em um valor é o erro de iniciante mais comum — a mensagem do validador é literalmente "Double quotes delimit identifiers in DynamoDB PartiQL, not strings. Use single quotes for string values." INusa colchetes, não parênteses:WHERE pk IN ['a','b'], limitado a 50 valores de PK / 100 valores de não-chave.- Sem
JOIN, sem agregados. Não existe motor para combinar tabelas ou dobrar linhas. Este é o tradeoff do design de tabela única: você modela para seus padrões de acesso de antemão porque a camada de consulta não consegue remodelar os dados depois do fato.
Por que assistentes de IA erram nisso
LLMs são treinados em oceanos de SQL relacional, então eles confiantemente emitem JOIN,
GROUP BY, LIKE, LIMIT inline e literais string entre aspas duplas contra o
DynamoDB — tudo o que o DynamoDB rejeita. O próprio autofix de consulta por modelo do DynoTable existe
justamente porque modelos baratos produzem esses padrões de forma confiável: ele remove
aspas com escape duplo, reescreve LIKE '%x%' → contains, IS NULL →
attribute_not_exists, e move o LIMIT inline para o parâmetro da requisição. Se a sua
IA está gerando "PartiQL" que se lê como Postgres, esse é o sinal.
A SQL Workbench do DynoTable: as consultas que o PartiQL não roda
Quando você genuinamente precisa de um JOIN ou de um GROUP BY, a SQL Workbench do DynoTable é
a resposta. Ela valida o lado de destino de cada JOIN contra uma chave de partição, materializa
as linhas unidas através do runtime real de Query/Scan do DynamoDB, e então roda um único
SELECT (agregados, GROUP BY, DISTINCT, CASE, CAST) por cima — SQL dentro das
regras de padrão de acesso do DynamoDB.
-- Runs in the DynoTable Workbench (NOT in PartiQL):
SELECT c.country, COUNT(*) AS orders, SUM(o.total) AS revenue
FROM orders o
INNER JOIN customers c ON o.customerId = c.PK
GROUP BY c.country
ORDER BY revenue DESCRestrições honestas (a Workbench impõe o modelo de acesso do DynamoDB, ela não finge ser Postgres):
- Somente
INNER JOINeLEFT JOIN— o atributo de destino doONdeve ser uma chave de partição ou chave de partição de GSI. SemRIGHT/FULL/CROSS/ comma-join. - Sem self-joins ainda, sem subconsultas, sem tabelas derivadas, sem funções de janela.
- Joins e projeções operam sobre atributos escalares.
Se você só precisa compor condições e expressões de chave para a API bruta, o
DynamoDB Expression Builder gera o
FilterExpression / KeyConditionExpression correto sem a superfície PartiQL
alguma. Para PartiQL feito da forma certa, veja os exemplos de PartiQL desenvolvidos;
para dimensionar o custo de qualquer consulta, use a
calculadora de tamanho de item. Note que o PartiQL
nunca muda o formato da rede — os valores ainda trafegam como DynamoDB-JSON.
Escolhendo um cliente? Veja onde a Workbench se posiciona contra uma
GUI comum do DynamoDB ou o Dynobase.
FAQ
PartiQL é a mesma coisa que SQL?
Não. O PartiQL é uma linguagem de consulta compatível com SQL, mas no DynamoDB ele só expõe
operações que mapeiam para um único Get/Query/Scan/Put/Update/Delete. Não tem joins,
agregados, subconsultas ou GROUP BY.
O PartiQL do DynamoDB consegue fazer um JOIN?
Não. O PartiQL do DynamoDB não consegue unir tabelas. A SQL Workbench do DynoTable consegue rodar
INNER/LEFT JOIN (para uma chave de partição ou chave de partição de GSI) materializando os
dados através do runtime de consulta real do DynamoDB.
O PartiQL do DynamoDB suporta GROUP BY ou COUNT?
Não — não existem agregados ou GROUP BY no PartiQL do DynamoDB. Use a SQL
Workbench do DynoTable para consultas COUNT/SUM/AVG/GROUP BY/HAVING.
Por que meu SELECT * custa tanto?
Sem uma chave de partição no WHERE, o PartiQL roda um Scan de tabela inteira e mede
cada item lido antes de o filtro ser aplicado. Adicione um predicado de chave de partição para transformá-lo
em um Query.
Devo usar aspas simples ou duplas no PartiQL?
Aspas simples para valores string ('CUSTOMER#42'), aspas duplas para identificadores
como nomes de tabela e atributo ("AppData"). Colocar aspas duplas em um valor é o
erro mais comum de PartiQL.
Pronto para rodar SQL real contra o DynamoDB? Baixe o DynoTable e abra uma aba da Workbench.