4 điểm bởi GN⁺ 2023-10-16 | 1 bình luận | Chia sẻ qua WhatsApp
  • Là client PostgreSQL dùng trong Node.js và Deno, lấy ES6 tagged template strings làm API cốt lõi và được cài đặt dưới dạng gói npm postgres
  • Tham số truy vấn được xử lý trước khi nội suy, thay thế bằng placeholder của giao thức PostgreSQL $1, $2, ...; các giá trị được truyền riêng tới cơ sở dữ liệu để cơ sở dữ liệu xử lý việc escape và casting
  • Lời gọi sql``...`` hỗ trợ tạo truy vấn an toàn và xây dựng truy vấn động, xử lý truy vấn từng phần, bộ lọc động, sắp xếp động, cũng như cấu thành định danh tên bảng/tên cột mà không có rủi ro SQL injection do nối chuỗi thông thường
  • Kết nối có thể được cấu hình bằng URL postgres://, object tùy chọn, hoặc dựa trên các biến môi trường dùng trong psql; giá trị trong object tùy chọn sẽ ghi đè giá trị trong URL
  • Truy vấn được thực thi khi được await, và kết quả được trả về dưới dạng mảng Result ánh xạ tên cột vào từng object hàng; có thể dùng .execute() để thực thi ngay lập tức
  • Luồng sử dụng chính gồm insert/update động, insert nhiều hàng, danh sách giá trị where in, transaction sql.begin, savepoint, prepared transaction, truy vấn dựa trên file, cursor, và các phương thức truy vấn nâng cao như .forEach, .describe, .values, .raw
  • Tích hợp với các tính năng PostgreSQL như LISTEN/NOTIFY, đăng ký thời gian thực dựa trên giao thức logical replication, expose stream Node.js cho COPY ..., và hỗ trợ hủy truy vấn đang chạy
    • Đăng ký thời gian thực cần tạo publication trong cơ sở dữ liệu, đặt wal_level = logical trong postgresql.conf, và kết nối bằng replication user hoặc superuser
    • API stream COPY ... không cung cấp type safety; cần khớp tham số truy vấn copy với mã đọc/ghi stream Node.js và xử lý backpressure
  • Tùy chọn chuyển đổi dữ liệu hỗ trợ chuyển đổi giữa camelCase, PascalCase, Kebab-Case và snake_case, chuyển đổi giá trị undefined, cùng các hàm chuyển đổi column/value/row do người dùng định nghĩa
  • Connection pool được tạo lười khi truy vấn được tạo; số kết nối tối đa mặc định là max: 10, và trong transaction, kết nối được giữ riêng từ pool rồi trả lại sau khi kết thúc
  • Hỗ trợ TCP socket API của Cloudflare Workers; để chạy trong môi trường Workers, cần đặt compatibility_flags = ["nodejs_compat"] trong wrangler.toml
  • Hỗ trợ TypeScript nhằm cung cấp kiểu cho API công khai, nhưng có hạn chế là khi thêm hoặc thay đổi tính năng, kiểu không phải lúc nào cũng được cập nhật đồng thời

1 bình luận

 
GN⁺ 2023-10-16
Ý kiến trên Hacker News
  • Nếu muốn tận dụng những điểm hay của Postgres và viết SQL trực tiếp, làm việc với thư viện này thực sự rất thú vị
    Không có những lớp trừu tượng hào nhoáng giả vờ hiện đại như Prisma, cũng không có chú thích kiểu phức tạp như các thư viện TypeScript khác; chỉ cần viết các câu SQL bình thường đúng chất JavaScript
    Vài năm trước, tôi chán việc phải gò mình theo Prisma nên bắt đầu học Postgres cho đúng và thử nhiều lựa chọn khác nhau; sau khi dùng cái này vài phút, tôi cảm thấy mình sẽ không quay lại nữa

    • Ước gì JavaScript cũng có một thư viện như Ecto của Elixir. Trong các công cụ xử lý SQL mà tôi từng thấy, đó là thứ tốt nhất: đơn giản, mạnh mẽ và dễ hiểu
    • Tôi chưa bao giờ thích cách chồng thêm các lớp lên trên SQL. SQL là thứ tôi không muốn bị tước khỏi tay ngay cả khi chết
    • Nhận lại loại code này sau khi một lập trình viên có trách nhiệm rời công ty chắc hẳn sẽ vui lắm. Không có kiểu, không chú thích, không trừu tượng, không migration; chỉ còn SQL thuần
    • Tôi tò mò bạn không thích điểm nào ở tính năng raw query của Prisma
  • Thư viện này nhanh đúng nghĩa. Đừng chỉ nhìn cú pháp template string tương tự rồi so sánh với các thư viện khác mà bỏ lỡ điểm cốt lõi
    Nó không phụ thuộc vào pg mà tự triển khai client cấp thấp riêng
    Tôi đã dùng nó để xây một hệ thống nạp nhiều đợt bản ghi, mỗi đợt 10 nghìn bản ghi, và hiệu năng vượt trội

    • Nói cụ thể hơn, có thể nạp khoảng 10 nghìn đến 20 nghìn bản ghi trong dưới 20ms, trong khi tác vụ đó vốn sẽ mất khoảng 150ms
      Tùy use case, chỉ riêng điều này cũng có thể thay đổi cục diện; nếu bạn quen với mức mà mình nghĩ là khả thi trong các môi trường như Ruby thì còn ấn tượng hơn
      Ngoài ra nó cũng hỗ trợ logical decoding, mở ra nhiều khả năng cho xử lý sự kiện chuyển tiếp. Đây là một dự án thật sự ấn tượng, bỏ qua thì rất tiếc
  • Bài liên quan:
    Show HN: Postgres.js – Fastest Full-Featured PostgreSQL Client for Node and Deno - https://news.ycombinator.com/item?id=30794332 - tháng 3/2022, 83 bình luận
    Show HN: Postgres.js – Fast PostgreSQL Client for Node.js - https://news.ycombinator.com/item?id=21864245 - tháng 12/2019, 12 bình luận

  • Có thể không nhiều tính năng bằng thư viện trong bài gốc, nhưng https://pgtyped.dev/ cũng hữu ích
    Nếu viết truy vấn dưới dạng file SQL, pgtyped sẽ tạo ra các hàm có kiểu để gọi với tham số truy vấn

  • Tôi là tác giả. Muốn bổ sung rằng giờ cũng hỗ trợ Cloudflare

  • Tôi thích việc nó có 0 dependency

    • Thời nay việc đó đủ hiếm để đáng nhấn mạnh riêng
  • Tôi tò mò câu “prepared statement được tự động tạo cho mọi truy vấn có thể suy luận là truy vấn tĩnh” thực sự có nghĩa là gì
    Có phải ngay cả khi không có biến binding và truy vấn đó chỉ chạy một lần, một prepared statement thực sự vẫn được tạo trong phiên DB không?
    Nếu vậy thì thú vị, nhưng có vẻ là một cách tiếp cận mang quan điểm khá mạnh

    • Nếu dùng truy vấn tham số hóa thì bắt buộc phải dùng extended query flow của PostgreSQL, và nhiều người sẽ xem đó là prepared statement. Bản thân việc này không hẳn là một lựa chọn mang quan điểm mạnh
      Tuy nhiên thông thường người ta dùng prepared statement hoặc portal không tên, và PostgreSQL sẽ dọn dẹp chúng, nên về thực tế chỉ giữ một cái cho mỗi session, tức mỗi connection
      Tôi không hiểu câu đó nên đã xem code; ý ở đây là tự động dùng prepared statement có tên để cache prepared statement trong PostgreSQL và bên trong driver. Nó đang tạo signature cho câu lệnh, nên đây chắc chắn là một thiết kế có chủ kiến
      Cá nhân tôi thấy phần code nơi chủ yếu tạo dữ liệu parse/describe/bind/execute/sync khá không ổn: https://github.com/porsager/postgres/blob/bf082a5c0ffe214924...
    • Postgres hỗ trợ hai loại prepared statement. Có generic prepared statement có thể nhận tham số, và custom prepared statement được chuẩn bị cho một lần thực thi cụ thể, đưa tham số vào kế hoạch thực thi
      Nội dung này được giải thích tại https://www.postgresql.org/docs/current/sql-prepare.html; xem phần “Notes” để biết loại kế hoạch
  • Có lẽ cũng nên nhắc đến Zapatos ở đây. Đây là một client Postgres JavaScript khác có thiết kế rất giống, viết SQL trong template string, nhưng cung cấp type safety đầy đủ
    Nếu bạn thích TypeScript thì có thể sẽ thích: https://jawj.github.io/zapatos/
    Cá nhân tôi thấy đây là một trong những thư viện TypeScript được thiết kế và viết tài liệu tốt nhất, và tiếc là nó không được biết đến nhiều

    • Cuối cùng tôi phải bỏ Zapatos. Nó không hỗ trợ nhiều schema, và kiểu sinh ra không phải lúc nào cũng dễ đọc
      Tôi chọn PgTyped làm phương án thay thế, và sau 2 năm thì thấy việc chuyển đổi là quyết định rất đúng
    • Đồng ý. Nhờ tính năng lateral join và tổ hợp các hàm rút gọn, việc xây backend trong khi vẫn viết SQL thật sự trở nên rất dễ mà không phải hy sinh khả năng sử dụng
    • Nhìn qua thì có vẻ Zapatos không tương thích với Cloudflare Workers; nếu không phải vậy thì mong được đính chính
    • Tôi tò mò có ai biết vì sao zapatos phụ thuộc vào pg thay vì PostgresJs không
  • Tôi tò mò dự án này đã tồn tại bao lâu nên đã xem thử:
    v1.0.1 - tháng 1/2020
    v2.0.0 - tháng 6/2020, nhưng dường như không thoát khỏi beta
    v3.0.0 - tháng 3/2022, từ lúc này dự án có vẻ mới thực sự bắt đầu
    Trông khá thú vị nên tôi cũng tò mò nó vững chắc đến mức nào

    • Tôi đã dùng trong môi trường production với Deno một thời gian. Khá vững, nhưng tài liệu còn thiếu nhiều, nên khi làm các tác vụ phức tạp thường phải tự mày mò tìm cách
  • Postgres.js là một trong những thư viện tốt nhất tôi từng dùng
    Cách nó tận dụng template của JavaScript thật sự rất trực quan