2011-07-15 6 views
1

J'essaye de créer une base de données de sqlite3 comme environnement de test qui imite l'environnement de production. En raison de la façon dont la production est configurée, les tables sont dans plusieurs schémas.Comment créer des clés étrangères dans des bases de données sqlite attachées?

J'ai configuré les classes dans DBIx :: Class, en utilisant $schema->storage->dbh_do pour attacher la base de données avec le schéma, et en utilisant $schema-deploy() pour créer la base de données.

Cependant, quand il vient à créer la clé étrangère sur la deuxième table, je reçois l'erreur suivante:

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

enlevons DBIx::Class le test le plus simple de se reproduire est la suivante. La suppression du schéma de la clause de clé étrangère permettra de créer la table.

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> 

Comment puis-je créer les tables dans le schéma étranger avec DBIx :: Class?

EDIT: un exemple complet du code.

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; 

Le script principal:

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(); 

L'erreur est donnée:

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 
+0

vous préférez utiliser le « autre ». pour garder votre code propre/plus simple? –

+0

Je n'ai vraiment aucune préférence. Ma préférence est que DBIx :: Class :: Schema :: deploy() génère une instruction create table qui fonctionnera sur SQLite. –

+0

Pouvez-vous poster votre code perl car il me semble que votre problème est avec perl, pas la syntaxe de sqlite. –

Répondre

2

réponse simple est que vous ne pouvez pas (et ne pas besoin de) préciser le nom de base de données avec le nom de la table dans les définitions de clé étrangère. Le docs sqlite l'indique comme tel.

Ce lien montre comment vous pouvez utiliser le nom de base de données avec le nouveau nom de la table dans la « create table db.table » partie:

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

Alors que ce lien montre comment vous ne pouvez pas utiliser nom de la base dans la définition de clé étrangère:

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

+1

Mais que se passe-t-il si la base de données attachée a le même nom de table que la base de données principale? Comment spécifieriez-vous une relation de clé étrangère qui résout cette ambiguïté? – vargonian

Questions connexes