FC2ブログ
2009
02.06

DBIx + postgres

Category: 未分類
華麗にはめられたので、メモ。

postgres 用のスキーマファイルを作ろうと思ったんです!
前に教えてもらったワンライナーをちょっといぢれば楽勝だぜうほほと思って

perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./ -e\
'make_schema_at "Dbname::Schema" , {relationships => 1, \
components => [qw/ InflateColumn::DateTime PK::Auto /], debug => 1},\ ["dbi:pgsql:Dbname","USERNAME"]'



ってしたら、DBIxさんが怒るんです。


DBIx::Class::Schema::Loader::make_schema_at(): DBI Connection failed: install_driver(pgsql) failed: Can't locate DBD/pgsql.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at (eval 63) line 3.
Perhaps the DBD::pgsql perl module hasn't been fully installed,
or perhaps the capitalisation of 'pgsql' isn't right.
Available drivers: DBM, ExampleP, File, Gofer, Multiplex, Pg, Proxy, SQLite, Sponge, mysql.
at /usr/local/share/perl/5.10.0/DBIx/Class/Storage/DBI.pm line 839



ぽすぐれは、pgsql ではなくて、Pgのようです。

修正修正。


perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./ -e\
'make_schema_at "Dbname::Schema" , {relationships => 1, \
components => [qw/ InflateColumn::DateTime PK::Auto /], debug => 1},\ ["dbi:Pg:DBNAME","USERNAME"]'




DBI connect('DBNAME','postgres',...) failed: missing "=" after "dbname" in connection info string at /usr/local/share/perl/5.10.0/DBIx/Class/Storage/DBI.pm line 839
DBIx::Class::Schema::Loader::make_schema_at(): DBI Connection failed: missing "=" after "DBNAME" in connection info string at -e line 1



あああああ?????
てきとにぐぐっても何も出てこないので、ソースを読むことにしました。

/usr/local/share/perl/5.10.0/DBIx/Class/Storage/DBI.pm line 839:

dbh = DBI->connect(@info);



うん、まぁ connect で失敗してますよね。

DBD::Pg での指定の仕方が違うのかな、と思って見てみたら

$dbh = DBI->connect("dbi:Pg:dbname=$dbname", '', '', {AutoCommit => 0});



と例が。

これかあああああ!!!!!!!!!!

いや、まてよ。

てかさ、DB名とか、ユーザ名とか、ホスト名とか、パスワードとかの渡し方って
共通じゃないのん??

それともDBIx::Class::Schema::Loader から呼ぶ時だけ違うの??

これは調べたらわかりそうなんで、見てみることに。

DBIx::Class

Then you can use these classes in your application's code:

# Connect to your database.
use DB::Main;
my $schema = DB::Main->connect($dbi_dsn, $user, $pass, \%dbi_params);



おおう、やっと理解。
dsnに、dbnameまで含まれてるんだねぇ…。
そこは、例えば、DBD::Pg とDBD::mysql とでは、内容が違うということか。

なんか微妙に釈然としないけど、dbname がないものもあったんかな。

DBM, ExampleP, File, Gofer, Multiplex, Pg, Proxy, SQLite, Sponge, mysql

全部調べればいいのか!

DBD::DBM:

use DBI;
$dbh = DBI->connect('dbi:DBM:');


DBD::ExampleP 関係なさそう。テスト用?

DBD::File

DBI:CSV:f_dir=$dirname;


とかするらしい。


DBD::Gofer

A stateless-proxy driver for communicating with a remote DBI


ステートレスプロキシなので割愛

DBD::Multiplex

DBD::Multiplex is a Perl module which works with the DBI allowing you to work with multiple datasources using a single DBI handle.


わーお、こんなもんもあるのか。
てか1つのDBIハンドルで動かす意味はなんだろう…。まとまるから??


DBD::Pg

$dbh = DBI->connect("dbi:Pg:dbname=$dbname", '', '', {AutoCommit => 0});



DBD::Proxy
DBD::Gofer を見ろだって。

DBD::SQLite

my $dbh = DBI->connect("dbi:SQLite:dbname=dbfile","","");


Pgと同じ感じですねぇ。ユーザ名とパスワードはないようです。undef でもいいのかな?


DBD::Sponge

DBIの関数でどうにもならんのを追加したりするためのものみたい?

DBD::mysql

$dsn = "DBI:mysql:database=$database;host=$hostname;port=$port";
$dbh = DBI->connect($dsn, $user, $password);


あれ?こんな書き方してたっけ…。

DBIのとこでは

Examples of $data_source values are:
dbi:DriverName:database_name
dbi:DriverName:database_name@hostname:port
dbi:DriverName:database=database_name;host=hostname;port=port



つまり、どれでもいいってこと???

mysql で試したら、
dbi:DriverName:database_name も dbi:DriverName:database=database_name も通ったのだけど、postgress は、dbi:DriverName:database_name の形式はやっぱりエラーになります。

そんなときは、ソース嫁ということで。。

DBD::Pgのソースを眺めてみると…。

sub connect { ## no critic (ProhibitBuiltinHomonyms)
    my ($drh, $dbname, $user, $pass, $attr) = @_;
    ## Allow "db" and "database" as synonyms for "dbname"
    $dbname =~ s/\b(?:db|database)\s*=/dbname=/;



これわ…そのままDBI側が渡してしまってるってことでしょうか。

ということで、結論。


dbi:DriverName:database=database_name;host=hostname;port=port
の形式で書いておけば、データベースが変わっても、DriverName を変更するだけですむ


かもしれない!


てか、この考察があってるかどうかという問題が(ぉ





えーと、追記しました。



ああでも、作ったSchema から connect すると
my $schema = Hoge::Schema->connect("dbi:Pg:hogehoge","username");
で普通にいけるわ…


ああもう、何なのこれwwwwwww


さらに追記(2/9)
やっぱだめでした。
connect は通るけど、その後 resultset してふがほげするとエラーが出ます。
スポンサーサイト



トラックバックURL
http://noriko3.blog42.fc2.com/tb.php/163-3dd1788b
トラックバック
コメント
管理者にだけ表示を許可する
 
back-to-top