4 puntos por GN⁺ 2023-10-16 | 1 comentarios | Compartir por WhatsApp
  • Es un cliente PostgreSQL para Node.js y Deno, con ES6 tagged template strings como API principal, instalado mediante el paquete npm postgres
  • Los parámetros de consulta se procesan antes de la interpolación y se reemplazan por placeholders del protocolo PostgreSQL $1, $2, ...; los valores se envían por separado a la base de datos, de modo que la base de datos se encarga del escape y el casting
  • Las llamadas sql``...`` admiten la generación segura de consultas y la composición dinámica de queries, y permiten manejar consultas parciales, filtros dinámicos, ordenamientos dinámicos y la construcción de identificadores de nombres de tablas y columnas sin el riesgo de SQL injection propio de concatenar strings normales
  • La conexión se puede configurar con una URL postgres://, un objeto de opciones o variables de entorno usadas por psql; los valores del objeto de opciones sobrescriben los de la URL
  • Las consultas se ejecutan cuando se les aplica await, y los resultados se devuelven como un arreglo Result que mapea los nombres de columnas a cada objeto de fila; con .execute() se pueden ejecutar de inmediato
  • El flujo principal de uso incluye insert/update dinámicos, insert de múltiples filas, listas de valores para where in, transacciones con sql.begin, savepoints, prepared transactions, consultas basadas en archivos, cursores y métodos avanzados de consulta como .forEach, .describe, .values y .raw
  • En integración con funcionalidades de PostgreSQL, admite LISTEN/NOTIFY, suscripciones en tiempo real basadas en el protocolo de replicación lógica, exposición de streams de Node.js para COPY ... y cancelación de consultas en curso
    • Las suscripciones en tiempo real requieren crear una publication en la base de datos, configurar wal_level = logical en postgresql.conf y conectarse con un usuario de replicación o superuser
    • La API de streams para COPY ... no ofrece type safety, y se deben coordinar los parámetros de la consulta copy con el código de lectura/escritura de streams de Node.js y el manejo de backpressure
  • Las opciones de transformación de datos admiten conversiones entre camelCase, PascalCase, Kebab-Case y snake_case, conversión de valores undefined y funciones personalizadas de transformación de column/value/row
  • El pool de conexiones se crea de forma diferida cuando se construye una consulta; el máximo de conexiones predeterminado es max: 10, y durante una transacción se reserva una conexión del pool para devolverla al finalizar
  • Compatible con la API de TCP socket de Cloudflare Workers; para funcionar en el entorno Workers se necesita configurar compatibility_flags = ["nodejs_compat"] en wrangler.toml
  • El soporte de TypeScript busca proporcionar tipos para la API pública, pero tiene la limitación de que los tipos no siempre se actualizan junto con cada agregado o cambio de funcionalidad

1 comentarios

 
GN⁺ 2023-10-16
Opiniones en Hacker News
  • Si quieres escribir SQL directo y aprovechar las buenas funciones de Postgres, trabajar con esta biblioteca es un verdadero placer.
    No hay abstracciones vistosas que pretenden ser modernas como Prisma, ni anotaciones de tipos complicadas como en otras bibliotecas de TypeScript; simplemente escribes sentencias SQL normales, como corresponde en JavaScript.
    Hace unos años me harté de forzar Prisma para que encajara, empecé a aprender Postgres en serio y probé varias alternativas; después de usar esta unos minutos, sentí que no volvería atrás.

    • Me gustaría que JavaScript tuviera una biblioteca como Ecto de Elixir. Es la mejor herramienta para trabajar con SQL que he visto hasta ahora: simple, potente y fácil de entender.
    • Nunca me gustó mucho la idea de poner capas encima de SQL. A SQL no me lo quitan de las manos ni muerto.
    • Debe ser muy divertido hacerse cargo de este código después de que el desarrollador responsable se va de la empresa. Sin tipos, sin comentarios, sin abstracciones, sin migraciones; solo SQL puro.
    • Me da curiosidad qué no te gustó de la función de raw query de Prisma.
  • Esta biblioteca es realmente rápida. No hay que quedarse en compararla con otras bibliotecas solo porque tengan una sintaxis parecida de plantillas de strings y perderse lo importante.
    No depende de pg; implementa su propio cliente de bajo nivel.
    Con esto construí un sistema que cargaba registros en tandas de 10 mil varias veces, y el rendimiento fue abrumador.

    • Para explicarlo un poco más: podía cargar unos 10 mil a 20 mil registros en menos de 20 ms, algo que normalmente habría tardado unos 150 ms.
      Según el caso de uso, eso por sí solo puede cambiar las reglas del juego, y resulta aún más impresionante si estás acostumbrado a los estándares que uno creería posibles en entornos como Ruby.
      Además, también soporta decodificación lógica, lo que abre muchas posibilidades para procesar eventos de transición. Es un proyecto realmente impresionante; sería una pena pasarlo por alto.
  • Artículos relacionados:
    Show HN: Postgres.js – Fastest Full-Featured PostgreSQL Client for Node and Deno - https://news.ycombinator.com/item?id=30794332 - marzo de 2022, 83 comentarios
    Show HN: Postgres.js – Fast PostgreSQL Client for Node.js - https://news.ycombinator.com/item?id=21864245 - diciembre de 2019, 12 comentarios

  • Puede que no tenga tantas funciones como la biblioteca del artículo original, pero https://pgtyped.dev/ también me resultó útil.
    Si escribes las consultas como archivos SQL, pgtyped genera funciones tipadas que puedes llamar con los parámetros de la consulta.

  • Soy el autor. Quiero agregar que ahora también soporta Cloudflare.

  • Me gusta que tenga 0 dependencias.

    • Hoy en día eso es lo bastante raro como para destacarlo aparte.
  • Me da curiosidad qué significa realmente la frase “se generan automáticamente sentencias preparadas para todas las consultas que se puedan inferir como consultas estáticas”.
    ¿Quiere decir que, aunque no haya variables vinculadas y esa consulta se ejecute una sola vez, se crea una sentencia preparada real en la sesión de la DB?
    Si es así, es interesante, pero parece un enfoque con una postura bastante fuerte.

    • Si usas consultas parametrizadas, necesariamente tienes que usar el flujo de consultas extendido de PostgreSQL, y mucha gente considerará eso una sentencia preparada. Eso en sí no es una elección particularmente opinada.
      Sin embargo, normalmente se usa una sentencia preparada sin nombre o un portal, y PostgreSQL se encarga de limpiarlos, de modo que en la práctica se mantiene solo uno por sesión, es decir, por conexión.
      No entendía esa frase, así que miré el código; aquí se refiere a que usa automáticamente sentencias preparadas con nombre para cachear sentencias preparadas dentro de PostgreSQL y del driver. Está creando una firma de la sentencia, así que definitivamente es un diseño opinado.
      Personalmente, el código donde se generan principalmente los datos de parse/describe/bind/execute/sync me parece bastante malo: https://github.com/porsager/postgres/blob/bf082a5c0ffe214924...
    • Postgres soporta dos tipos de sentencias preparadas. Están las sentencias preparadas genéricas, que pueden recibir parámetros, y las sentencias preparadas custom, que se preparan para una ejecución específica e incorporan los parámetros en el plan.
      Está explicado en https://www.postgresql.org/docs/current/sql-prepare.html; para los tipos de plan, mira la sección “Notes”.
  • Creo que aquí también habría que mencionar Zapatos. Es otro cliente JavaScript para Postgres con un diseño muy parecido, en el que escribes SQL dentro de strings de plantilla, pero ofrece seguridad de tipos completa.
    Si te gusta TypeScript, podría gustarte: https://jawj.github.io/zapatos/
    Personalmente, me parece una de las bibliotecas de TypeScript mejor diseñadas y documentadas, y me da pena que no sea más conocida.

    • Al final tuve que abandonar Zapatos. No soportaba varios schemas y los tipos no siempre salían fáciles de leer.
      Elegí PgTyped como alternativa, y ahora, dos años después, realmente creo que fue un gran acierto cambiar.
    • De acuerdo. Gracias a la función de lateral join y a la combinación de funciones abreviadas, es muy fácil construir un backend sin renunciar a escribir SQL real ni a la usabilidad.
    • A primera vista, parece que Zapatos no es compatible con Cloudflare Workers; si no es así, me gustaría que me corrigieran.
    • Me da curiosidad si alguien sabe por qué zapatos depende de pg y no de PostgresJs.
  • Me dio curiosidad saber qué tan viejo era este proyecto, así que revisé:
    v1.0.1 - enero de 2020
    v2.0.0 - junio de 2020, pero no salió de beta
    v3.0.0 - marzo de 2022; desde entonces parece que el proyecto empezó en serio.
    Se ve bastante interesante, y también me pregunto qué tan sólido es.

    • Lo he usado durante un tiempo en producción con Deno. Es bastante sólido, pero la documentación deja mucho que desear; cuando haces tareas complejas, muchas veces tienes que tantear por tu cuenta hasta encontrar cómo hacerlo.
  • Postgres.js está entre las mejores bibliotecas que he usado hasta ahora.
    La forma en que aprovecha las plantillas de JavaScript es realmente intuitiva.