<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/postgresql-adapter-for-python-x3bopdb7k" -->

---
title: PostgreSQL adapter for Python | daily.dev
description: An in-depth look at the redesigned adaptation system in psycopg3, the successor to the popular psycopg2 PostgreSQL adapter for Python. The new system moves...
canonical: https://daily.dev/posts/postgresql-adapter-for-python-x3bopdb7k
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: PostgreSQL adapter for Python | daily.dev
og:description: An in-depth look at the redesigned adaptation system in psycopg3, the successor to the popular psycopg2 PostgreSQL adapter for Python. The new system moves...
og:url: https://daily.dev/posts/postgresql-adapter-for-python-x3bopdb7k
og:image: https://api.daily.dev/og/posts/x3BoPDb7K.png
og:image:alt: PostgreSQL adapter for Python
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# PostgreSQL adapter for Python

**[Psycopg](https://daily.dev/sources/psycopg)** · 6 min read · 0 upvotes · 0 comments

## Summary

An in-depth look at the redesigned adaptation system in psycopg3, the successor to the popular psycopg2 PostgreSQL adapter for Python. The new system moves from client-side to server-side parameter binding using the extended query protocol, bringing performance gains, prepared statement support, and binary data handling, but introduces some backward-incompatible changes such as restrictions on multi-statement queries, SET/NOTIFY with parameters, and IN (...) constructs. It also covers the new Dumper and Loader classes for customizing type conversion, with examples like mapping Python's date.max to PostgreSQL's infinity date. The piece closes with a call for project sponsorship to fund full-time development.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.psycopg.org/articles/2020/11/24/psycopg3-adaptation>

## Questions this post answers

### What breaks when migrating from psycopg2 to psycopg3 due to server-side parameter binding?

Server-side binding in psycopg3 cannot send more than one query at once when parameters are used, cannot use commands like SET or NOTIFY with parameters (must use set_config or pg_notify functions instead), and cannot use the IN (...) construct (must use the 'any' function instead). These are non-backward-compatible changes from psycopg2's client-side binding approach.

_daily.dev surfaces migration gotchas like these for developers upgrading their Postgres driver._

### How do I make psycopg3 treat Python's date.max as PostgreSQL infinity date?

Create a subclass of the builtin DateDumper that checks if the object equals date.max and returns b'infinity' instead of delegating to the parent dump method, then register it with InfDateDumper.register(date, cur). A symmetric InfDateLoader subclass can be registered to convert PostgreSQL's infinity date back into date.max when loading query results.

_daily.dev helps Python developers track adapter customization patterns like this for PostgreSQL._

### Why does psycopg3 use server-side parameter binding instead of client-side like psycopg2?

Psycopg3 uses the PostgreSQL extended query protocol, sending query parameters separately from the query text via libpq's PQexecParams instead of merging quoted values into a single query string. This brings better performance, support for prepared statements and binary data, and improved integration with server-side logging and monitoring compared to psycopg2's client-side quoting approach.

_daily.dev keeps developers deciding between database driver architectures informed on trade-offs like these._

---

Tags: [#python](https://daily.dev/tags/python), [#sql](https://daily.dev/tags/sql), [#postgresql](https://daily.dev/tags/postgresql)

[View this post on daily.dev](https://daily.dev/posts/postgresql-adapter-for-python-x3bopdb7k)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"PostgreSQL adapter for Python","url":"https://daily.dev/posts/postgresql-adapter-for-python-x3bopdb7k","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/postgresql-adapter-for-python-x3bopdb7k"},"datePublished":"2026-08-23T12:21:52.327Z","dateModified":"2026-08-23T12:40:13.373Z","description":"An in-depth look at the redesigned adaptation system in psycopg3, the successor to the popular psycopg2 PostgreSQL adapter for Python. The new system moves...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/b0cbd2ac8948f96ab39fa6a90db7464f?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/b0cbd2ac8948f96ab39fa6a90db7464f?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Psycopg","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Psycopg","logo":"https://media.daily.dev/image/upload/s--5N-KNNWk--/f_auto,q_auto/v1787487485/logos/psycopg?_a=BAMAMicg0","url":"https://daily.dev/sources/psycopg"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/postgresql-adapter-for-python-x3bopdb7k","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"python,sql,postgresql","timeRequired":"PT6M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Psycopg","item":"https://daily.dev/sources/psycopg"},{"@type":"ListItem","position":3,"name":"PostgreSQL adapter for Python"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/postgresql-adapter-for-python-x3bopdb7k#faq","mainEntity":[{"@type":"Question","name":"What breaks when migrating from psycopg2 to psycopg3 due to server-side parameter binding?","acceptedAnswer":{"@type":"Answer","text":"Server-side binding in psycopg3 cannot send more than one query at once when parameters are used, cannot use commands like SET or NOTIFY with parameters (must use set_config or pg_notify functions instead), and cannot use the IN (...) construct (must use the 'any' function instead). These are non-backward-compatible changes from psycopg2's client-side binding approach. daily.dev surfaces migration gotchas like these for developers upgrading their Postgres driver."}},{"@type":"Question","name":"How do I make psycopg3 treat Python's date.max as PostgreSQL infinity date?","acceptedAnswer":{"@type":"Answer","text":"Create a subclass of the builtin DateDumper that checks if the object equals date.max and returns b'infinity' instead of delegating to the parent dump method, then register it with InfDateDumper.register(date, cur). A symmetric InfDateLoader subclass can be registered to convert PostgreSQL's infinity date back into date.max when loading query results. daily.dev helps Python developers track adapter customization patterns like this for PostgreSQL."}},{"@type":"Question","name":"Why does psycopg3 use server-side parameter binding instead of client-side like psycopg2?","acceptedAnswer":{"@type":"Answer","text":"Psycopg3 uses the PostgreSQL extended query protocol, sending query parameters separately from the query text via libpq's PQexecParams instead of merging quoted values into a single query string. This brings better performance, support for prepared statements and binary data, and improved integration with server-side logging and monitoring compared to psycopg2's client-side quoting approach. daily.dev keeps developers deciding between database driver architectures informed on trade-offs like these."}}]}
```

