我試圖建立一個數據庫,其相關位如下所示。我在Arch Linux上使用SQLite3(3.8.8.3-1),並使用DBIx :: Class 0.082820。DBIx :: Class has_one <-> might_have relationship
它是一個簡單的簿記系統的一部分。發票行has_one交易,但僅交易might_have對應的發票行(因爲可以創建一些沒有發票的交易)。
我無法獲取DBIx :: Class以便一次插入發票行及其相應的事務。錯誤信息也在下面。
我做錯了嗎?或者做一些沒有道理的事情?
爲什麼它從搜索具有相同描述的現有事務開始?
這裏是我的簡化得多的測試用例的血淋淋的細節:
InvoiceLine.pm:
package Test::DB::Schema::Result::InvoiceLine;
use strict;
use warnings;
use base 'DBIx::Class::Core';
__PACKAGE__->table("invoice_lines");
__PACKAGE__->add_columns(
"id",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
"txn_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0,
is_deferrable => 1 }, # tried this, but it doesn't help
'details',
{ data_type => 'text', is_nullable => 0 },
);
__PACKAGE__->set_primary_key("id");
# Invoice line has an associated transaction
__PACKAGE__->has_one(
"txn",
"Test::DB::Schema::Result::Transaction",
'id',
);
# Experimental -- this doesn't work either
#__PACKAGE__->belongs_to(
# "txn",
# "Test::DB::Schema::Result::Transaction",
# "txn_id",
#);
1;
Transaction.pm:
use utf8;
package Test::DB::Schema::Result::Transaction;
use strict;
use warnings;
use base 'DBIx::Class::Core';
__PACKAGE__->table("transactions");
__PACKAGE__->add_columns(
"id",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
'description',
{ data_type => 'text', is_nullable => 0 },
# Invoice line
# Null if no associated invoice
'invoice_line_id',
{data_type => 'integer', is_nullable => 1 },
);
__PACKAGE__->set_primary_key("id");
# Some transactions have a single corresponding
# invoice line
__PACKAGE__->might_have(
"invoice_line",
"Test::DB::Schema::Result::InvoiceLine",
'id',
{ cascade_copy => 0, cascade_delete => 0 },
);
# EXPERIMENTAL == this doesn't work either
# might_have isn't working, so try has_many (where many can be 0):
#__PACKAGE__->has_many(
# 'invoice_lines',
# "Test::DB::Schema::Result::InvoiceLine",
# 'txn_id',
#);
1;
Test.pl
#!/usr/bin/perl
# Test.pl
# Testing might_have <-> has_one relationship
use Test::DB::Schema;
my $schema = Test::DB::Schema->connect(
"dbi:SQLite:dbname=dbic_test.db", '', '', {}
);
$schema->deploy({ add_drop_table => 1 } , '.');
$schema->storage->debug(1);
my $data1 = {
details => 'abc',
txn => {
description => 'xyz',
}
};
my $new1 = $schema->resultset('InvoiceLine')->create($data1);
結果的運行Test.pl是:
BEGIN WORK
SELECT me.id, me.description, me.invoice_line_id FROM transactions me WHERE (me.description = ?): 'xyz'
INSERT INTO transactions (description) VALUES (?): 'xyz'
INSERT INTO invoice_lines (details, id) VALUES (?, ?): 'abc', '1'
DBIx::Class::Storage::DBI::_dbh_execute(): DBI Exception: DBD::SQLite::st execute failed: NOT NULL constraint failed: invoice_lines.txn_id [for Statement "INSERT INTO invoice_lines (details, id) VALUES (?, ?)"] at ./Test.pl line 16
DBIx::Class::Storage::TxnScopeGuard::DESTROY(): A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or error. Rolling back. at /usr/share/perl5/site_perl/DBIx/Class/Exception.pm line 77
ROLLBACK
感謝您的回答 - 我會嘗試明天。 –
我試過了,它的工作原理!幾乎。請參閱下面的答案。 –