4 pontos por GN⁺ 2023-10-16 | 1 comentários | Compartilhar no WhatsApp
  • Cliente PostgreSQL para Node.js e Deno, com ES6 tagged template strings como API principal e instalação pelo pacote npm postgres
  • Os parâmetros de consulta são processados antes da interpolação e substituídos por placeholders do protocolo PostgreSQL $1, $2, ...; os valores são enviados separadamente ao banco de dados, que fica responsável por escape e casting
  • Chamadas sql``...`` oferecem criação segura de consultas e composição dinâmica, lidando com consultas parciais, filtros dinâmicos, ordenação dinâmica e identificadores de nomes de tabelas e colunas sem o risco de SQL injection causado por concatenação de strings comuns
  • A conexão pode ser configurada por uma URL postgres://, por um objeto de opções ou com base nas variáveis de ambiente usadas pelo psql; valores do objeto de opções sobrescrevem os valores da URL
  • As consultas são executadas quando recebem await, e o resultado é retornado como um array Result que mapeia os nomes das colunas para cada objeto de linha; com .execute(), é possível executar imediatamente
  • O fluxo principal de uso inclui insert/update dinâmico, insert de várias linhas, listas de valores para where in, transações com sql.begin, savepoints, prepared transactions, consultas baseadas em arquivos, cursores e métodos avançados de consulta como .forEach, .describe, .values e .raw
  • Na integração com recursos do PostgreSQL, oferece suporte a LISTEN/NOTIFY, assinaturas em tempo real baseadas no protocolo de replicação lógica, exposição de streams do Node.js para COPY ... e cancelamento de consultas em andamento
    • As assinaturas em tempo real exigem a criação de uma publication no banco de dados, wal_level = logical no postgresql.conf e conexão com um usuário de replication ou superuser
    • A API de stream de COPY ... não oferece segurança de tipos; é preciso alinhar os parâmetros da consulta copy com o código de leitura/escrita de streams do Node.js e o tratamento de backpressure
  • As opções de transformação de dados suportam conversão entre camelCase, PascalCase, Kebab-Case e snake_case, conversão de valores undefined e funções personalizadas de transformação de column/value/row
  • O pool de conexões é criado de forma preguiçosa quando uma consulta é criada; o número máximo padrão de conexões é max: 10, e durante uma transação a conexão é reservada do pool e devolvida após o término
  • Suporta a TCP socket API do Cloudflare Workers; para funcionar no ambiente Workers, é necessário definir compatibility_flags = ["nodejs_compat"] no wrangler.toml
  • O suporte a TypeScript busca fornecer tipos para a API pública, mas há a limitação de que os tipos nem sempre são atualizados junto com adições ou mudanças de funcionalidade

1 comentários

 
GN⁺ 2023-10-16
Opiniões no Hacker News
  • Se você quer aproveitar os bons recursos do Postgres e escrever SQL diretamente, trabalhar com esta biblioteca é realmente prazeroso
    Não há abstrações vistosas fingindo ser modernas, como Prisma, nem anotações de tipo complicadas como em outras bibliotecas TypeScript; é só escrever instruções SQL comuns, do jeito JavaScript
    Alguns anos atrás, cansei de tentar encaixar Prisma à força, comecei a aprender Postgres de verdade e experimentei várias alternativas; depois de usar esta por alguns minutos, senti que não voltaria atrás

    • Seria bom se JavaScript tivesse uma biblioteca como o Ecto do Elixir. Foi a melhor ferramenta para lidar com SQL que já vi até agora: simples, poderosa e fácil de entender
    • Nunca gostei muito da ideia de empilhar camadas em cima de SQL. SQL é algo que eu não gostaria que me tirassem das mãos nem depois de morto
    • Deve ser muito divertido assumir esse código depois que o desenvolvedor responsável sair da empresa. Sem tipos, sem comentários, sem abstrações, sem migrações; sobra apenas SQL puro
    • Fico curioso para saber do que você não gostou no recurso de raw query do Prisma
  • Esta biblioteca é realmente rápida. Não se deve comparar com outras bibliotecas olhando apenas para a sintaxe parecida de template string e perder o ponto principal
    Ela não depende de pg; implementou seu próprio cliente de baixo nível
    Criei com ela um sistema que carregava registros em lotes de 10 mil várias vezes, e o desempenho foi esmagador

    • Explicando melhor: era possível carregar algo em torno de 10 mil a 20 mil registros em menos de 20 ms, uma operação que normalmente levaria cerca de 150 ms
      Dependendo do caso de uso, só isso já pode mudar o jogo, e é ainda mais impressionante se você está acostumado aos padrões que achava possíveis em ambientes como Ruby
      Além disso, ela também oferece suporte a decodificação lógica, abrindo várias possibilidades para processamento de eventos transitórios. É um projeto realmente impressionante; seria uma pena ignorá-lo
  • Posts relacionados:
    Show HN: Postgres.js – Fastest Full-Featured PostgreSQL Client for Node and Deno - https://news.ycombinator.com/item?id=30794332 - março de 2022, 83 comentários
    Show HN: Postgres.js – Fast PostgreSQL Client for Node.js - https://news.ycombinator.com/item?id=21864245 - dezembro de 2019, 12 comentários

  • Talvez não tenha tantos recursos quanto a biblioteca do post original, mas https://pgtyped.dev/ também foi útil
    Se você escreve as consultas em arquivos SQL, o pgtyped gera funções tipadas que podem ser chamadas com os parâmetros da consulta

  • Sou o autor. Quero acrescentar que agora também há suporte ao Cloudflare

  • Gosto do fato de ter 0 dependências

    • Hoje em dia isso é raro o suficiente para merecer destaque
  • Fico curioso para saber o que a frase “instruções preparadas são criadas automaticamente para toda consulta que possa ser inferida como estática” quer dizer na prática
    Isso significa que uma instrução preparada real é criada na sessão do banco mesmo que não haja variáveis de bind e mesmo que a consulta seja executada apenas uma vez?
    Se for isso, é interessante, mas parece uma abordagem com uma posição bastante forte embutida

    • Se você usa consultas parametrizadas, necessariamente precisa usar o fluxo de consulta estendido do PostgreSQL, e muita gente consideraria isso uma instrução preparada. Isso, por si só, não é uma escolha particularmente opinativa
      Porém, normalmente se usa uma instrução preparada sem nome ou um portal sem nome, e o PostgreSQL faz a limpeza disso, de modo que, na prática, fica mantida apenas uma por sessão, ou seja, por conexão
      Não entendi aquela frase, então olhei o código: o que eles querem dizer é que usam automaticamente instruções preparadas nomeadas para fazer cache das instruções preparadas tanto no PostgreSQL quanto dentro do driver. Como eles criam uma assinatura da instrução, isso é claramente uma decisão de design opinativa
      Pessoalmente, acho bem ruim o código onde os dados de parse/describe/bind/execute/sync são montados em grande parte: https://github.com/porsager/postgres/blob/bf082a5c0ffe214924...
    • O Postgres oferece suporte a dois tipos de instruções preparadas: instruções preparadas generic, que podem receber parâmetros, e instruções preparadas custom, que são preparadas para uma execução específica e incorporam os parâmetros ao plano
      Isso é explicado em https://www.postgresql.org/docs/current/sql-prepare.html; para o tipo de plano, veja a seção “Notes”
  • Acho que Zapatos também deveria ser mencionado aqui. É outro cliente Postgres para JavaScript com um design muito parecido, em que se escreve SQL dentro de template strings, mas com segurança de tipos completa
    Se você gosta de TypeScript, pode gostar dele: https://jawj.github.io/zapatos/
    Pessoalmente, sinto que é uma das bibliotecas TypeScript com melhor design e documentação, e é uma pena que não seja mais conhecida

    • Acabei tendo que desistir do Zapatos. Ele não dava suporte a múltiplos schemas, e os tipos nem sempre ficavam fáceis de ler
      Escolhi o PgTyped como alternativa e, dois anos depois, acho que foi uma decisão realmente acertada
    • Concordo. Graças ao recurso de lateral join e à combinação de funções de atalho, fica muito fácil criar backends escrevendo SQL real sem abrir mão da usabilidade
    • À primeira vista, parece que o Zapatos não é compatível com Cloudflare Workers; gostaria de ser corrigido se eu estiver enganado
    • Fico curioso para saber por que o zapatos depende de pg em vez de PostgresJs
  • Fiquei curioso para saber há quanto tempo este projeto existe, então fui olhar:
    v1.0.1 - janeiro de 2020
    v2.0.0 - junho de 2020, mas nunca saiu do beta
    v3.0.0 - março de 2022, quando o projeto parece ter começado para valer
    Parece bastante interessante, e também fico curioso para saber o quão robusto ele é

    • Usei em ambiente de produção no Deno por um bom tempo. É bastante sólido, mas a documentação deixa muito a desejar; ao fazer tarefas complexas, muitas vezes é preciso ir tateando por conta própria para descobrir como proceder
  • Postgres.js está entre as melhores bibliotecas que já usei até agora
    A forma como ela aproveita templates do JavaScript é realmente intuitiva