【问题标题】:How do you create foreign keys in attached sqlite databases?如何在附加的 sqlite 数据库中创建外键?
【发布时间】:2011-07-16 14:13:28
【问题描述】:

我正在尝试创建一个 sqlite3 数据库作为模拟生产环境的测试环境。由于生产的设置方式,这些表位于多个模式中。

我已经在 DBIx::Class 中设置了类,使用 $schema->storage->dbh_do 将数据库与架构附加在一起,并使用 $schema-deploy() 创建数据库。

但是,在第二个表上创建外键时,出现以下错误:

DBIx::Class::Schema::deploy(): DBIx::Class::Schema::deploy(): DBI Exception: DBD::SQLite::db do failed: near ".": syntax error 

带走DBIx::Class最简单的复现测试如下。

sqlite3 initial.db
SQLite version 3.6.23
Enter ".help" for instructions
Enter SQL statements terminated with a ";"   
sqlite> attach database 'other.db' as 'other';
sqlite> create table other.a( col1_a, col2_a);
sqlite> create table other.b( col1_b, col2_b, foreign key(col1_b) references other.a(col1_a));
Error: near ".": syntax error
sqlite> create table other.b( col1_b, col2_b, foreign key(col1_b) references a(col1_a));
sqlite> 

从外键子句中删除架构将成功创建表。

如何使用 DBIx::Class 在外部模式中创建表?

编辑:完整的代码示例。

package MyApp::Schema;
use base qw/DBIx::Class::Schema/;
__PACKAGE__->load_namespaces();
1;


package MyApp::Schema::Result::A;
use base qw/DBIx::Class::Core/;
__PACKAGE__->table('other_db.A');
__PACKAGE__->add_columns(qw/ a1 a2 /);
__PACKAGE__->set_primary_key('a1');
__PACKAGE__->has_many(bs => 'MyApp::Schema::Result::B', 'b1');
1;

package MyApp::Schema::Result::B;
use base qw/DBIx::Class::Core/;
__PACKAGE__->table('other_db.B');
__PACKAGE__->add_columns(qw/ b1 b2 /);
__PACKAGE__->set_primary_key('b1');
__PACKAGE__->belongs_to(a => 'MyApp::Schema::Result::A', 'b1');
1;

主脚本:

use MyApp::Schema;

my $schema = MyApp::Schema->connect('dbi:SQLite:dbname=test.db','','',{});

my $res = $schema->storage->dbh_do(
    sub {
        my ($storage, $dbh) = @_;
        $dbh->do("attach database 'other.db' as other_db");
    }
);

$schema->deploy();

给出的错误是:

DBIx::Class::Schema::deploy(): DBIx::Class::Schema::deploy(): DBI Exception: DBD::SQLite::db do failed: near ".": syntax error [for Statement "CREATE TABLE other_db.B (
  b1  NOT NULL,
  b2  NOT NULL,
  PRIMARY KEY (b1),
  FOREIGN KEY(b1) REFERENCES other_db.A(a1)
)"] at dbi.pl line 17
 (running "CREATE TABLE other_db.B (
  b1  NOT NULL,
  b2  NOT NULL,
  PRIMARY KEY (b1),
  FOREIGN KEY(b1) REFERENCES other_db.A(a1)
)") at dbi.pl line 17

【问题讨论】:

  • 所以你更喜欢使用“其他”。让你的代码更干净/更简单?
  • 我真的没有偏好。我的偏好是 DBIx::Class::Schema::deploy() 生成一个适用于 SQLite 的 create table 语句。
  • 你能发布你的 perl 代码吗,因为在我看来你的问题是 perl,而不是 sqlite 的语法。

标签: perl sqlite dbix-class


【解决方案1】:

简单的答案是,当在外键定义中使用表名时,您不能(也不需要)指定数据库名。 sqlite 文档表明了这一点。

此链接显示了如何在“create table db.table”部分中将数据库名称与新表名一起使用:

http://www.sqlite.org/lang_createtable.html

而此链接显示您如何不能在外键定义中使用数据库名称:

http://www.sqlite.org/syntaxdiagrams.html#foreign-key-clause

【讨论】:

  • 但是如果附加数据库与主数据库具有相同的表名怎么办?您将如何指定解决这种歧义的外键关系?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-02
  • 2015-04-19
  • 2015-05-30
  • 2014-04-07
  • 2014-04-12
相关资源
最近更新 更多