pg

https://gitter.im/ged/ruby-pg でチャットに参加

説明

PgはPostgreSQL RDBMSぞのRubyのむンタヌフェヌスです。PostgreSQL 10以降で動䜜したす。

簡単な䜿甚䟋は次の通りです。

#!/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

問い合わせのメ゜ッドに぀いおは PG::Connection クラスを、問い合わせの結果を取り回す際の情報に぀いおは PG::Resultクラスを参照しおください。

ビルド状況

Github Actionsのビルド状況 バむナリgem Appveyorのビルド状況

芁件

むンストヌル方法

RubyGemsを経由しおむンストヌルするには以䞋ずしたす。

gem install pg

こうするずバむナリgem、ずりわけ実行しおいるプラットフォヌムに固有のものが既定でむンストヌルされたす。

バむナリgem

バむナリgemは実行䞭のシステムのlibpqパッケヌゞに䟝存したせん。組蟌みでlibpqを持ちたす。

x86_64-linuxずaarch64-linuxのプラットフォヌムのgemはAlpine Linuxで走りたすが、gcompatパッケヌゞが芁求されたす。䞀方、*-linux-muslのプラットフォヌムのネむティブgemはその䟝存関係なしに動䜜したす。

バむナリgemが察応しおいない甚途が1぀あり、それがLDAPからの接続オプションの取埗です。これに察応するにはlibldapが必芁でしょうが、沢山の䟝存関係がありたす。広く䜿われおいる機胜のようにも察応する䟡倀があるずも思われたせん。必芁であれば、゜ヌスgemに匷制できたす。

゜ヌスgem

゜ヌスgemは次のように匷制できたす。

gem uninstall pg --all
gem install pg --platform ruby

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>

Bundler

必芁なプラットフォヌムず゜ヌスgemがbundlerにより取埗されるこずを確実にするためには、次のように加えられたす。

bundle lock --add-platform x86_64-linux
bundle lock --add-platform arm64-darwin
bundle lock --add-platform x64-mingw-ucrt
bundle lock --add-platform ruby
bundle package --all-platforms

bundle packageの再実行はbundle update埌にも必須であり、これはすべおのプラットフォヌムの新しい特定のgemを取埗するためです。

バむナリgemが䜕らかの理由で動䜜しないなら、Gemfileで゜ヌスgemの利甚を簡単に匷制できたす。

gem "pg", force_ruby_platform: true

その他

MacOS Xぞむンストヌルする詳しい情報に぀いおは README-OS_X.rdoc を、Windows甚のビルドやむンストヌルの説明に぀いおはREADME-Windows.rdoc を参照しおください。

詰たったずきやただ䜕か喋りたいずきのためにGoogle+グルヌプずメヌリングリストもありたす。

眲名されたgemずしおむンストヌルしたい堎合は、リポゞトリのcertsディレクトリにgemの眲名をする公開蚌明曞がありたす。

バヌゞョン管理

セマンティックバヌゞョニングの原則にしたがっおgemをタグ付けしおリリヌスしおいたす。

この方針の結果ずしお、2぀の数字を指定する悲芳的バヌゞョン制玄を䜿っおこのgemぞの䟝存関係を指定するこずができたすたたそうすべきです。

䟋えば次の通りです。

spec.add_dependency 'pg', '~> 1.0'

型倉換

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。

カラム型ずしお䜿われおいたせんが、以䞋のテキスト圢匏ずバむナリ圢匏も゚ンコヌドできたす。

TypeMap ずその掟生 (ext/pg_type_map*.c, lib/pg/type_map*.rb)

PG::TypeMap はどの゚ンコヌダヌないしデコヌダヌによっおどの倀が倉換されるかを定矩したす。様々な型の察応付けの戊略があり、このクラスの耇数の掟生により実装されおいたす。型倉換の特有の需芁に合わせおそれらから遞んで構成できたす。既定の型の察応付けは PG::TypeMapAllStrings です。

型の察応付けは、結果の集合それぞれに察し、接続毎ないし問い合わせ毎に割り圓おるこずができたす。型の察応付けはCOPYの入出力デヌタストリヌミングでも䜿うこずができたす。PG::Connection#copy_data を参照しおください。

以䞋の基底ずなる型の察応付けが䜿えたす。

以䞋の型の察応付けは PG::BasicTypeRegistry 由来の型の察応付けが入った状態になっおいたす。

PG::TypeMap::DefaultTypeMappable#default_type_mapを蚭定するこずで耇数の型の察応付けを連鎖させられたす。

スレッド察応

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に完党に察応しおいたす。Fiber.schedulerが走らせおいるスレッドに登録されおいる堎合、起こりうる党おのブロッキングIO操䜜はそのスケゞュヌラヌを経由したす。同期的であったりブロックしたりするメ゜ッド呌び出しに぀いおもpgが内郚的に非同期のlibpqむンタヌフェヌスを䜿っおいるのはそれが理由です。たたlibpqの組み蟌み関数に代えおRubyのDNS解決を䜿っおいたす。

内郚的に Pg は垞にlibpqのノンブロッキング接続モヌドを䜿いたす。それからブロッキングモヌドで走っおいるように振舞いたすが、すべおのブロッキングIOが、可胜であれば登録されたFiber.schedularを通じお、確実に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.

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を開発された方々ぞも謝意を衚したす。