9 comments

  • noduerme2 hours ago
    Somewhat off topic, as someone who hasn&#x27;t used PostgreSQL and only has experience with mysql&#x2F;MariaDB... I&#x27;ve never liked writing queries with numbered parameters from an array with placeholders like $1 in this example. I find them much easier to read and debug when I pass them with string keys, basically:<p>`UPDATE t SET x=:x WHERE 1` `{x:42}`<p>I found that the original node-mysql didn&#x27;t even allow this, so I wrote my own parser on top of it. But I don&#x27;t see this style of binding used in examples very often. Is it frowned upon for some reason?
    • wvbdmp1 hour ago
      This is basically how we do it in .NET. With Dapper it’s particularly neat sometimes because you can just pass an object that you were using anyway, and it will match parameter names to its properties case-insensitively.<p>I.e.<p>Query(&quot;select * from MyTable where Id = @Id&quot;, myEntity)<p>The idiom is to use anonymous objects which you can new up inline like “new { id, age = 5 }”, where id is an existing variable that will automatically lend its name. So it’s pretty concise.<p>The syntax is Sql Server native (which supports named params at the protocol level), but the Npgsql dat provider converts it to PG’s positional system automatically.
    • n_e1 hour ago
      PostgreSQL uses the format $1, $2 in the protocol, so I think it&#x27;s just that nobody has bothered to implement named parameters in clients.<p>In another style, postgres.js uses calls such as sql`select * from t where id = ${variable}` (which is safe because it&#x27;s a tagged template, not string interpolation).
  • afidrya2 hours ago
    Is there a way to make this work with <a href="https:&#x2F;&#x2F;github.com&#x2F;porsager&#x2F;postgres" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;porsager&#x2F;postgres</a> ? It&#x27;s very close to raw SQL but with safe substitutions. I use it with Zod, but it would be great to have the types derived automatically.
    • n_e1 hour ago
      Unfortunately I haven&#x27;t found a way to make it work.<p>It would be quite easy to extract the queries to compute the types, but TypeScript doesn&#x27;t handle tagged template literals well enough to link the query passed to the sql`` template to the return type.
  • 1-more2 hours ago
    If you&#x27;re into Haskell prior art, there&#x27;s postgresql-typed <a href="https:&#x2F;&#x2F;hackage.haskell.org&#x2F;package&#x2F;postgresql-typed-0.6.2.5&#x2F;docs&#x2F;Database-PostgreSQL-Typed.html#g:5" rel="nofollow">https:&#x2F;&#x2F;hackage.haskell.org&#x2F;package&#x2F;postgresql-typed-0.6.2.5...</a> where you write queries, it safely(?) puts in your variables, and you automatically get back typed values.
    • n_e2 hours ago
      Very interesting, thanks!<p>I see they use the same global approach as pg-typed (asking for a ParameterDescription &#x2F; RowDescription, which aren&#x27;t usually exposed by the PG drivers), but there are interesting differences in the details. Also this made me realise that I could also type enums automatically.
  • johnfn1 hour ago
    Seems very cool, if it works :) My suggestion here would be to provide a TS playground environment where I can inspect and poke around to see that the types really do work. I&#x27;d also love to see some more complex queries with joins, etc.
  • netghost1 hour ago
    Thank you. This looks like a nice improvement on pgtyped, and another good option.<p>I&#x27;m curious if there are any good patterns for dealing with dynamic query building or composing queries?
    • n_e1 hour ago
      I haven’t found a good way to handle dynamic queries in pg-typesafe yet.<p>For now, I type these manually, which is acceptable for my usage as they are pretty rare compared to static queries.
  • barishnamazov3 hours ago
    How is this different than kysely + kysely-codegen (or hand-made types)?
    • n_e2 hours ago
      Kysely is a query builder: you build queries by calling javascript functions, while with pg-typesafe you write SQL directly.<p>I&#x27;ve used kysely before creating pg-typesafe, and came to the conclusion that writing SQL directly is more convenient.<p>A query builder works well for simple cases (db.selectFrom(&quot;t&quot;).where(&quot;id&quot;,&quot;=&quot;,&quot;1&quot;) looks a lot like the equivalent SQL), however, for more complicated queries it all falls apart. I often had to look at the docs to find how to translate some predicate from SQL to the required idiom. Also, I don&#x27;t think kysely can automatically infer the return type of PostgreSQL functions, while pg-typed does (it asks PostgreSQL for it).
    • ZiiS2 hours ago
      It only changes the types; not the code.
  • semiquaver2 hours ago
    How is this different from sqlc with sqlc-gen-typescript?
    • n_e2 hours ago
      I didn&#x27;t look too much into sqlc-gen-typescript because the project looks abandoned (no commits in 2 years, many open PRs).<p>Regarding sqlc in general, it is focused on having the SQL queries in .sql files, while pg-typed is focused on having the queries inline (though I plan to add .sql file support). I like the latter approach better, as for small queries used in only one place, it is a little cumbersome to add them to a different file and find a name for them.
  • MuffinFlavored1 hour ago
    any reason why you did<p><pre><code> const { rows } = client.query( &quot;select id, name, last_modified from tbl where id = $1&quot;, [42], ); </code></pre> instead of<p><pre><code> const { rows } = client.query( &quot;select id, name, last_modified from tbl where id = :id&quot;, { id: 42 }, );</code></pre>
    • n_e1 hour ago
      That is the way node-postgres works. pg-typesafe adds type safety but doesn’t change the node-postgres methods
  • dbbk2 hours ago
    Just use Drizzle