nikkie-ftnextの日記

イベントレポートや読書メモを発信

psycopg2, psycopg2-binary, psycopg, psycopg-binary、いっぱいあってワケワカンナイヨー

はじめに

七尾百合子さん、お誕生日 147日目 おめでとうございます! nikkieです。

全部同じじゃないですか!?」と違いが理解できていない私1(記事執筆前)に、「これだからしろうとはだめだ」が聞こえてきました。

目次

きっかけ:SQLAlchemyインストール時のextra

Pythonパッケージをインストールするときに[]を使ってextra(追加の依存パッケージ群)を指定できます。
https://pip.pypa.io/en/stable/cli/pip_install/#examples の7

SQLAlchemyにもたくさんのextraがあります。
https://pypi.org/project/SQLAlchemy/
Provides-Extraにズラッと並んでいます。

このうち以下4つの違いはなんなのか気になりました。
https://github.com/sqlalchemy/sqlalchemy/blob/rel_2_0_42/setup.cfg#L62-L70

[options.extras_require]
postgresql = psycopg2>=2.7
postgresql_psycopg2binary = psycopg2-binary
postgresql_psycopg = psycopg>=3.0.7
postgresql_psycopgbinary = psycopg[binary]>=3.0.7

調べて分かったことまとめ

GPT-5 deep researchに質問して得られたレポートのリンクに当たって理解した内容を書いていきます。
再現性のために共有:https://gist.github.com/ftnext/31bb7ef696f4afa8a8bf8097704e471d

  • psycopg2 の後の3系psycopg で提供されている(認識できていなかった)
    • 新規プロジェクトなら psycopg (3系を使う)
  • psycopg2 と psycopg2-binary のうち、前者が本番利用に向く
  • 3系を使う時、psycopg[binary]とextraを指定するとよい

psycopgの2系と3系

Django Girls Tutorialのextensionsでは、(SQLiteの代わりに)PostgreSQLを導入しています。
https://tutorial-extensions.djangogirls.org/ja/optional_postgresql_installation/

(myvenv) ~/djangogirls$ pip install psycopg2

私の認識はここで止まっていました。
また、Herokuに無料でデプロイできた頃、psycopg2が入らない場合はpsycopg2-binaryを使うというworkaroundも聞き及んでいました。

実は4年前の2021年にpsycopg 3系がリリースされています!

記事執筆時点のpsycopg2(2.9.10)には

The psycopg2 package is still widely used and actively maintained, but it is not expected to receive new features.

Psycopg 3 is the evolution of psycopg2 and is where new features are being developed: if you are starting a new project you should probably start from 3!

psycopg2のメンテナンスは続くものの、新機能はpsycopg 3系に追加されるため、新規プロジェクトではpsycopg 3系の利用が勧められています。

著名なライブラリの事例だと、Djangoは4.2でpsycopg 3系をサポートしていました(2系と両方サポート)。
https://docs.djangoproject.com/en/5.2/releases/4.2/#psycopg-3-support

https://github.com/django/django/blob/5.2.5/django/db/backends/postgresql/base.py#L4 より

Requires psycopg2 >= 2.8.4 or psycopg >= 3.1.8

psycopg2 と psycopg2-binary

ズバリなドキュメント
https://www.psycopg.org/docs/install.html#psycopg-vs-psycopg-binary

The psycopg2-binary package is meant for beginners to start playing with Python and PostgreSQL without the need to meet the build requirements.

If you are the maintainer of a published package depending on psycopg2 you shouldn’t use psycopg2-binary as a module dependency. For production use you are advised to use the source distribution.

  • psycopg2-binary は初心者向け
    • ビルド要件を満たさなくてもインストールできる
  • psycopg2 に依存するパッケージのメンテナならば、psycopg2-binaryを依存に使うべきではない

https://pypi.org/project/psycopg2-binary/ を見ても

The binary package is a practical choice for development and testing but in production it is advised to use the package built from sources.

psycopg と psycopg-binary

3系のpsycopgは2系とは話が違ってくるようです。

まず psycopg-binary は、開発者が直接インストールしてはいけません。
https://pypi.org/project/psycopg-binary/

You shouldn’t install this package directly: use instead

pip install "psycopg[binary]"

pip install psycopg-binaryではなく、pip install "psycopg[binary]"2とextraを指定します。

インストールについてのドキュメントにも
https://www.psycopg.org/psycopg3/docs/basic/install.html

pip install "psycopg[binary]"       # remove [binary] for PyPy

とあります。

https://www.psycopg.org/psycopg3/docs/basic/install.html#binary-installation より

This will install a self-contained package with all the libraries needed.

必要なライブラリ (libpq など) が含まれるようです

同じページの中には

  • [c]というextraの指定もある(Local installation)
  • extraを指定しなければ Pure Python installation
    • システムの libpq が必要

psycopg2-binaryとは違って、本番利用ではpsycopg[binary]を使うべきでないという記述は見つけられていません(逆に真っ先に紹介される方法になっています)

ここまでを元に、SQLAlchemyのextraの指定を考える

[options.extras_require]
postgresql = psycopg2>=2.7
postgresql_psycopg2binary = psycopg2-binary
postgresql_psycopg = psycopg>=3.0.7
postgresql_psycopgbinary = psycopg[binary]>=3.0.7

私の意見

  • psycopg2 よりも psycopg のほうが最新バージョン(3系)
    • 新規プロジェクトでは3系を使いたい
  • postgresql_psycopg2binary は本番向けではないので、なるべく指定せず postgresql としたい
  • postgresql_psycopg と postgresql_psycopgbinary では postgresql_psycopgbinary ではないか
    • postgresql_psycopgbinary で入る psycopg[binary] が本番向けではないという情報は今回の範囲では見つからなかった
    • postgresql_psycopg ではPython実装しか入らないので、パフォーマンスが懸念?

終わりに

psycopg2, psycopg2-binary, psycopg, psycopg-binary の違いを押さえられました。
一番の収穫は、psycopg2 よりも3系の psycopg の方が新規プロジェクトでは向くということ。
FastAPIでPostgreSQLを使うことが多いですが、次からはpsycopgを指定していきます!