pg
-
ホーム :: github.com/ged/ruby-pg
-
ドキュメント :: deveiate.org/code/pg (英語)、 deveiate.org/code/pg/README_ja_md.html (日本語)
-
変更履歴 :: History.md
説明
PgはPostgreSQL RDBMSへのRubyのインターフェースです。PostgreSQL 9.3以降で動作します。
簡単な使用例は次の通りです。
#!/usr/bin/env ruby require 'pg' # データベースへの現在の接続を表に出力します conn = PG.connect( dbname: 'sales' ) conn.exec( "SELECT * FROM pg_stat_activity" ) do |result| puts " PID | User | Query" result.each do |row| puts " %7d | %-16s | %s " % row.values_at('pid', 'usename', 'query') end end
ビルド状況
要件
-
Ruby 2.5かそれより新しいバージョン
-
PostgreSQL 9.3.xかそれ以降のバージョン(ヘッダー付属のもの、例えば-devの名前のパッケージ)。
それより前のバージョンのRubyやPostgreSQLでも通常は同様に動作しますが、定期的なテストはされていません。
バージョン管理
セマンティックバージョニングの原則にしたがってgemをタグ付けしてリリースしています。
この方針の結果として、2つの数字を指定する悲観的バージョン制約を使ってこのgemへの依存関係を指定することができます(またそうすべきです)。
例えば次の通りです。
spec.add_dependency 'pg', '~> 1.0'
インストール方法
RubyGemsを経由してインストールするには以下とします。
gem install pg
Postgresと一緒にインストールされた‘pg_config’プログラムへのパスを指定する必要があるかもしれません。
gem install pg -- --with-pg-config=<path to pg_config>
Bundlerを介してインストールした場合は次のようにコンパイルのためのヒントを与えられます。
bundle config build.pg --with-pg-config=<path to pg_config>
MacOS Xへインストールする詳しい情報については README-OS_X.rdoc を、Windows用のビルドやインストールの説明についてはREADME-Windows.rdoc を参照してください。
詰まったときやただ何か喋りたいときのためにGoogle+グループとメーリングリストもあります。
署名されたgemとしてインストールしたい場合は、リポジトリの{certs
ディレクトリ}にgemの署名をする公開証明書があります。
型変換
Pgでは任意でRubyと素のCコードにある結果の値やクエリ引数の型変換ができます。こうすることでデータベースとのデータの往来を加速させられます。なぜなら文字列のアロケーションが減り、(比較的遅い)Rubyのコードでの変換部分が省かれるからです。
とても基本的な型変換は次のようにできます。
conn.type_map_for_results = PG::BasicTypeMapForResults.new conn # ……これは結果の値の対応付けに作用します。 conn.exec("select 1, now(), '{2,3}'::int[]").values # => [[1, 2014-09-21 20:51:56 +0200, [2, 3]]] conn.type_map_for_queries = PG::BasicTypeMapForQueries.new conn # ……そしてこれは引数値の対応付けのためのものです。 conn.exec_params("SELECT $1::text, $2::text, $3::text", [1, 1.23, [2,3]]).values # => [["1", "1.2300000000000000E+00", "{2,3}"]]
しかしPgの型変換はかなり調整が効きます。2層に分かれているのがその理由です。
エンコーダーとデコーダー (ext/pg_coder.c, lib/pg/coder.rb)
こちらはより低層で、DBMSへ転送するためにRubyのオブジェクトを変換するエンコーディングクラスと、取得してきたデータをRubyのオブジェクトに変換し戻すデコーディングクラスが含まれています。クラスはそれぞれの形式によって名前空間 PG::TextEncoder
, PG::TextDecoder
, PG::BinaryEncoder
, そしてPG::BinaryDecoder に分かれています。
エンコーダーないしデコーダーオブジェクトにOIDデータ型や形式コード(テキストないしバイナリ)や任意で名前を割り当てることができます。要素のエンコーダーないしデコーダーを割り当てることによって複合型を構築することもできます。PG::Coder オブジェクトは PG::TypeMap
をセットアップしたり、その代わりに単一の値と文字列表現とを相互に変換したりするのに使えます。
ruby-pgでは以下のPostgreSQLカラム型に対応しています(TE = Text Encoder、TD = Text Decoder、BE = Binary Encoder、BD = Binary Decoder)。
-
Timestamp:
カラム型として使われていませんが、以下のテキスト形式とバイナリ形式もエンコードできます。
PG::TypeMap
とその派生 (ext/pg_type_map.c, lib/pg/type_map.rb)
TypeMapはエンコーダーまたはデコーダーのどちらによってどの値を変換するかを定義します。様々な型の対応付け戦略があるので、このクラスにはいくつかの派生が実装されています。型変換の特有の需要に合わせてそれらの派生から選んで調整を加えることができます。既定の型の対応付けは PG::TypeMapAllStrings
です。
型の対応付けは、結果の集合それぞれに対し、接続毎ないしクエリ毎に割り当てることができます。型の対応付けはCOPYの入出力データストリーミングでも使うことができます。PG::Connection#copy_data を参照してください。
以下の基底となる型の対応付けが使えます。
-
PG::TypeMapAllStrings
- 全ての値と文字列について相互にエンコードとデコードを行います(既定) -
PG::TypeMapByClass
- 送信する値のクラスに基づいてエンコーダーを選択します -
PG::TypeMapByColumn
- カラムの順番によってエンコーダーとデコーダーを選択します -
PG::TypeMapByOid
- PostgreSQLのOIDデータ型によってデコーダーを選択します -
PG::TypeMapInRuby
- Rubyで独自の型の対応付けを定義します
以下の型の対応付けは PG::BasicTypeRegistry
由来の型の対応付けが入った状態になっています。
-
PG::BasicTypeMapForResults
-PG::TypeMapByOid
によくあるPostgreSQLカラム型用にデコーダーが入った状態になっています -
PG::BasicTypeMapBasedOnResult
-PG::TypeMapByOid
によくあるPostgreSQLカラム型用のエンコーダーが入った状態になっています -
PG::BasicTypeMapForQueries
-PG::TypeMapByClass
によくあるRubyの値クラス用にエンコーダーが入った状態になっています
スレッド対応
PGには個々のスレッドが別々の PG::Connection
オブジェクトを同時に使えるという点でスレッド安全性があります。しかし1つ以上のスレッドから同時にPgのオブジェクトにアクセスすると安全ではありません。そのため必ず、毎回新しいスレッドを作るときに新しいデータベースサーバー接続を開くか、スレッド安全性のある方法で接続を管理するActiveRecordのようなラッパーライブラリを使うようにしてください。
以下のようなメッセージが標準エラー出力に表示された場合、恐らく複数のスレッドが1つの接続を使っています。
message type 0x31 arrived from server while idle message type 0x32 arrived from server while idle message type 0x54 arrived from server while idle message type 0x43 arrived from server while idle message type 0x5a arrived from server while idle
Fiber IOスケジューラー対応
pg-1.3.0以降で、PgはRuby-3.0で導入されたFiber.scheduler
に完全に対応しています。Windowsでは、Fiber.scheduler
対応はRuby-3.1以降で使えます。Fiber.scheduler
が走らせているスレッドに登録されている場合、起こりうる全てのブロッキングIO操作はそのスケジューラーを経由します。同期的であったりブロックしたりするメソッド呼び出しについてもpgが内部的に非同期のlibpqインターフェースを使っているのはそれが理由です。またlibpqの組み込み関数に代えてRubyのDNS解決を使っています。
内部的にPgは常にlibpqのノンブロッキング接続モードを使います。それからブロッキングモードで走っているように振舞いますが、もしFiber.scheduler
が登録されていれば全てのブロッキングIOはそのスケジューラーを通じてRubyで制御されます。PG::Connection.setnonblocking(true)
が呼ばれたらノンブロッキング状態が有効になったままになりますが、それ以降のブロッキング状態の制御が無効になるので、呼び出しているプログラムはブロッキング状態を自力で制御しなければなりません。
この規則の1つの例外には、PG::Connection#lo_create
や外部ライブラリを使う認証メソッド(GSSAPI認証など)のような、大きめのオブジェクト用のメソッドがあります。これらはFiber.scheduler
と互換性がないため、ブロッキング状態は登録されたIOスケジューラに渡されません。つまり操作は適切に実行されますが、IO待ち状態に別のIOを扱うFiberから使用を切り替えてくることができなくなります。
Ractor対応
pg-1.5.0以降で、PgはRuby-3.0で導入されたRactorと完全な互換性があります。型エンコーダーないしデコーダー、及び型の対応付けがRactor.make_shareable
により凍結されている場合、これらをractor間で共有できます。また凍結された PG::Result
と PG::Tuple
オブジェクトも共有できます。少なくとも全ての凍結されたオブジェクト(ただし PG::Connection
を除く)はPostgreSQLサーバーとのやり取りをしたり取得されたデータを読むのに使えます。
PG::Connection
は共有できません。個々の接続を確立するために、それぞれのRactor内で作られなければなりません。
貢献
バグを報告したり機能を提案したりGitでソースをチェックアウトしたりするにはプロジェクトページをご確認ください。
ソースをチェックアウトしたあとは全ての依存関係をインストールします。
$ bundle install
拡張ファイル、パッケージファイル、テストデータベースを一掃するには、このコマンドを走らせてください。PostgreSQLのバージョンも切り替わります。
$ rake clean
拡張をコンパイルするには次のようにします。
$ rake compile
pg_config --bindir
が指すPostgreSQLのバージョンでテストやスペックを走らせるには次のようにします。
$ rake test
あるいは特定のPostgreSQLのバージョンで、ファイル中の行番号を使って特定のテストを走らせるには次のようにします。
$ PATH=/usr/lib/postgresql/14/bin:$PATH rspec -Ilib -fd spec/pg/connection_spec.rb:455
APIドキュメントを生成するには次のようにします。
$ rake docs
必ず全てのバグと新機能についてテストを使って検証してください。
現在のメンテナはMichael Granger ged@FaerieMUD.orgとLars Kanis lars@greiz-reinsdorf.deです。
著作権
Copyright © 1997-2022 by the authors.
-
Jeff Davis ruby-pg@j-davis.com
-
Guy Decoux (ts) decoux@moulon.inra.fr
-
Michael Granger ged@FaerieMUD.org
-
Lars Kanis lars@greiz-reinsdorf.de
-
Dave Lee
-
Eiji Matsumoto usagi@ruby.club.or.jp
-
Yukihiro Matsumoto matz@ruby-lang.org
-
Noboru Saitou noborus@netlab.jp
You may redistribute this software under the same terms as Ruby itself; see www.ruby-lang.org/en/about/license.txt or the BSDL file in the source for details.(参考訳:このソフトウェアはRuby自体と同じ条件の元で再配布することができます。詳細についてはwww.ruby-lang.org/en/about/license.txt やソース中のBSDLファイルを参照してください)
Portions of the code are from the PostgreSQL project, and are distributed “ ”under the terms of the PostgreSQL license, included in the file POSTGRES.(参考訳:コードの一部はPostgreSQLプロジェクトから来ており、PostgreSQLの使用許諾の条件の元で配布されます。ファイルPOSTGRESに含まれています)
Portions copyright LAIKA, Inc.
謝辞
長年にわたって貢献してくださった方々については Contributors.rdoc を参照してください。
ruby-listとruby-devメーリングリストの方々に感謝します。またPostgreSQLを開発された方々へも謝意を表します。