【发布时间】:2015-04-21 03:13:54
【问题描述】:
我正在尝试建立一个数据库,其相关部分如下所示。我在 Arch Linux 上使用 SQLite3 (3.8.8.3-1),DBIx::Class 0.082820。
这是一个简单的簿记系统的一部分。一个发票行has_one 交易,但一个交易只有可能有一个对应的发票行(因为有些交易可以在没有发票的情况下创建)。
我无法让 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
【问题讨论】:
标签: perl sqlite dbix-class