July 1st, 2024

Psycopg 3.2 released – PostgreSQL driver for Python

Psycopg 3.2 release brings Numpy scalar and PostgreSQL parameter format support, async enhancements, and PgBouncer interaction. It emphasizes maintaining crucial Python-PostgreSQL communication, aiding businesses and infrastructures with reliable interaction.

Read original articleLink Icon
Psycopg 3.2 released – PostgreSQL driver for Python

Psycopg 3.2 has been released after almost two years of development, bringing new features like support for Numpy scalars, PostgreSQL parameter formats, and a scalar row factory for easier data retrieval. Additionally, it now supports new features from libpq 17, enhancing asynchronous operations, stream results, and PgBouncer interaction. The release also includes improvements in handling notifications and reducing code duplication through async-to-sync conversion tools. Maintaining Psycopg is highlighted as crucial for Python and PostgreSQL users, encouraging sponsorship for ongoing development. The update aims to enhance the communication between Python and PostgreSQL, catering to various businesses and critical infrastructures. Psycopg 3 continues to be a vital tool for ensuring reliable and efficient interaction between the two technologies.

Link Icon 4 comments
By @JoelJacobson - 5 months
Author here of the PostgreSQL raw queries feature mentioned in the release notes, which allows users to use PostgreSQL's native placeholders ($1, $2, etc.) instead of the standard %s placeholder [1].

    from psycopg import connect, RawCursor
    
    with connect(dsn, cursor_factory=RawCursor) as conn:
        with conn.cursor() as cur:
            cur.execute("SELECT $1, $2", [1, "Hello"])
            assert cur.fetchone() == (1, "Hello")
The release notes highlight several interesting advantages I hadn't considered. However, they don't mention the primary motivation behind my contribution, so I thought I'd share it here:

I was concerned that psycopg replaces the %s placeholders using regexes, which might inadvertently alter my SQL queries. My goal was to ensure that my SQL queries were passed directly to PostgreSQL "as is," without any intermediate modifications. Only PostgreSQL's parser can safely and accurately parse all SQL queries. While this concern might seem theoretical if you're certain your queries don't contain any %s, it still felt much more reassuring to eliminate this potential source of bugs entirely.

[1] https://www.psycopg.org/psycopg3/docs/advanced/cursors.html#...

By @frou_dh - 5 months
I like that $1 etc can now be written instead of %s for placeholders in queries.

Even though the latter was already safe, it simply looked toe-curling (like you were writing naive SQL-injectable queries all the time).

By @whalesalad - 5 months
If you are operating in an environment with asyncio check out asyncpg - https://github.com/MagicStack/asyncpg

Performance charts speak for themselves. This lib uses the binary protocol while most are using text based comms.

By @odie5533 - 5 months
Everyone seems still on psycopg2. Is there a compelling reason to switch? Is Psycopg3 faster?