Как вы создаете внешние ключи в подключенных базах данных sqlite?

Я пытаюсь создать базу данных 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

person Todd Hunter    schedule 15.07.2011    source источник
comment
Поэтому вы предпочитаете использовать другой. в, чтобы ваш код был чище/простее?   -  person    schedule 15.07.2011
comment
У меня действительно нет предпочтений. Я предпочитаю, чтобы DBIx::Class::Schema::deploy() создавал оператор создания таблицы, который будет работать на SQLite.   -  person Todd Hunter    schedule 15.07.2011
comment
Можете ли вы опубликовать свой код perl, так как мне кажется, что ваша проблема связана с perl, а не с синтаксисом sqlite.   -  person    schedule 15.07.2011


Ответы (1)


Простой ответ заключается в том, что вы не можете (и не должны) указывать имя базы данных при использовании имени таблицы в определениях внешнего ключа. Документы sqlite указывают это как таковое.

Эта ссылка показывает, как вы можете использовать имя базы данных с новым именем таблицы в части «создать таблицу db.table»:

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

Принимая во внимание, что эта ссылка показывает, как вы не можете использовать имя базы данных в определении внешнего ключа:

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

person Community    schedule 15.07.2011
comment
Но что, если присоединенная база данных имеет то же имя таблицы, что и основная база данных? Как бы вы определили отношение внешнего ключа, которое разрешает эту неоднозначность? - person vargonian; 26.10.2012