Iniciante8 min de leitura

DynamoDB PartiQL vs SQL: o que é diferente (e o que quebra)

A maior fonte de confusão com o PartiQL do DynamoDB — tanto para humanos quanto para assistentes de AI — é tratá-lo como SQL relacional. Não é. O PartiQL é uma superfície compatível com SQL sobre as operações já existentes do DynamoDB, não um motor de consulta capaz de juntar, agrupar ou agregar. As palavras-chave familiares escondem uma máquina muito diferente por baixo.

O modelo mental

Toda instrução PartiQL é compilada para uma das operações nativas do DynamoDB:

Você escreveDynamoDB roda
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 capaz de 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 toda a história — 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:

WHERE pins full PKno PK in WHEREPartiQL statementSELECT?Query (one partition)Scan (whole table)INSERT PutItemUPDATE UpdateItemDELETE DeleteItem

Cada instrução resolve para exatamente uma operação nativa — esse mapeamento um-para-um é o motivo pelo qual o PartiQL não consegue juntar, agrupar ou agregar.

O que é diferente — recurso por recurso

Cada que o SQL Workbench do DynoTable consegue rodar está marcado. O Workbench materializa suas tabelas através do runtime de consulta real do DynamoDB e roda SQL de verdade por cima — SQL dentro das regras de padrão de acesso do DynamoDB.

RecursoSQL padrãoPartiQL do DynamoDBDynoTable Workbench
JOIN … ON … INNER / LEFT (para uma PK ou GSI partition key)
RIGHT / FULL / CROSS / comma-join
Self-join (ainda não)
Subconsultas / tabelas derivadas
CTEs (WITH …)
UNION / INTERSECT / EXCEPT
GROUP BY / HAVING
Agregações (COUNT/SUM/AVG/MIN/MAX)
DISTINCT
CASE / CAST
Window functions
ORDER BY qualquer coluna apenas sort key (precisa de WHERE com partition key) qualquer coluna
LIMIT inline (use o parâmetro limit da requisição)
LIKE (use contains / begins_with)
IS NULL / IS NOT NULL (use attribute_not_exists / attribute_exists)
SELECT * sem uma PKescaneia Scan de tabela inteira silencioso (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 chegar à rede — cada uma remete a uma restrição real do DynamoDB.

  • SELECT * sem uma partition key é um Scan escondido. O PartiQL não dá erro; ele simplesmente lê cada item e filtra depois, que é o clássico cilada de custo Query-vs-Scan por trás de uma sintaxe amigável.
  • UPDATE / DELETE precisam da chave primária completa. Eles mapeiam para um UpdateItem/DeleteItem de um único item, então o WHERE precisa fixar a partition key (e a sort key, em uma tabela de chave composta). Você não pode "atualizar todas as linhas onde status = 'open'" em uma única 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 um valor entre aspas duplas é o erro mais comum de iniciante — a mensagem do validador é literalmente "Double quotes delimit identifiers in DynamoDB PartiQL, not strings. Use single quotes for string values."
  • IN usa colchetes, não parênteses: WHERE pk IN ['a','b'], limitado a 50 valores de PK / 100 valores fora da chave.
  • Sem JOIN, sem agregações. Não existe motor para combinar tabelas ou dobrar linhas. Esse é o tradeoff do single-table-design: você modela para seus padrões de acesso de antemão porque a camada de consulta não consegue reformatar os dados depois do fato.

Por que assistentes de AI erram nisso

LLMs são treinados em oceanos de SQL relacional, então eles emitem com confiança JOIN, GROUP BY, LIKE, LIMIT inline e literais string entre aspas duplas contra o DynamoDB — todos rejeitados pelo DynamoDB. O autofix de consulta por modelo do próprio DynoTable existe justamente porque modelos baratos produzem esses padrões de forma confiável: ele remove aspas duplamente escapadas, reescreve LIKE '%x%'contains, IS NULLattribute_not_exists, e move o LIMIT inline para o parâmetro da requisição. Se sua AI está gerando "PartiQL" que parece Postgres, esse é o sinal.

Cada cartão mostra o SQL que um desenvolvedor relacional usaria, o que o PartiQL do DynamoDB realmente faz com ele e por quê. Os cartões marcados como “Roda no DynoTable” mostram o SQL equivalente que o Workbench consegue rodar.
Joining two tables
Não há no PartiQL
SELECT o.id, c.name
FROM orders o
JOIN customers c ON o.customerId = c.PK
GROUP BY and aggregates
Não há no PartiQL
SELECT country, COUNT(*) AS orders, SUM(total) AS revenue
FROM orders
GROUP BY country
Subqueries
Não há no PartiQL
SELECT * FROM orders
WHERE customerId IN (SELECT PK FROM customers WHERE country = 'ES')
UNION across tables
Não há no PartiQL
SELECT PK FROM orders
UNION
SELECT PK FROM archived_orders
SELECT * (the hidden Scan)
Funciona, com ressalvas
SELECT * FROM orders
Updating many rows by a filter
Não há no PartiQL
UPDATE orders SET status = 'shipped'
WHERE status = 'open'
Quoting string values
Funciona, com ressalvas
SELECT * FROM users WHERE "name" = "Alice"

O SQL Workbench do DynoTable: as consultas que o PartiQL não consegue rodar

Quando você realmente precisa de um JOIN ou um GROUP BY, o SQL Workbench do DynoTable é a resposta. Ele valida o lado de destino de cada JOIN contra uma partition key, materializa as linhas juntadas através do runtime real de Query/Scan do DynamoDB, e então roda seu SQL completo (agregações, 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 DESC

Restrições honestas (o Workbench impõe o modelo de acesso do DynamoDB, ele não finge ser Postgres):

  • Apenas INNER JOIN e LEFT JOIN — o atributo de destino do ON precisa ser uma partition key ou uma GSI partition key. Sem RIGHT / FULL / CROSS / comma-join.
  • Ainda sem self-joins, sem subconsultas, sem tabelas derivadas, sem window functions.
  • 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 do PartiQL de forma alguma. Para PartiQL feito direito, veja os exemplos de PartiQL resolvidos; para dimensionar quanto qualquer consulta vai custar, use a calculadora de tamanho de item. Note que o PartiQL nunca muda o formato de transmissão — os valores ainda viajam como DynamoDB-JSON. Escolhendo um cliente? Veja onde o Workbench se posiciona contra uma GUI comum do DynamoDB ou o Dynobase.

FAQ

O PartiQL é o mesmo 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. Ele não tem joins, agregações, subconsultas ou GROUP BY.

O PartiQL do DynamoDB consegue fazer um JOIN? Não. O PartiQL do DynamoDB não consegue juntar tabelas. O SQL Workbench do DynoTable consegue rodar INNER/LEFT JOIN (para uma partition key ou GSI partition key) 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 há agregações ou GROUP BY no PartiQL do DynamoDB. Use o SQL Workbench do DynoTable para consultas com COUNT/SUM/AVG/GROUP BY/HAVING.

Por que meu SELECT * custa tão caro? Sem uma partition key no WHERE, o PartiQL roda um Scan de tabela inteira e cobra cada item lido antes de o filtro ser aplicado. Adicione um predicado de partition key 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 um valor entre aspas duplas é o erro mais comum no PartiQL.

Pronto para rodar SQL de verdade contra o DynamoDB? Baixe o DynoTable e abra uma aba do Workbench.

Atualizado