2017-10-27 8 views
2

以下のコードで、テーブルt1に挿入するときにエラーが発生しないのはなぜですか? t1の列bは外部キーですので、t2の列cの値のみを受け入れる必要がありますが、どういうわけかエラーなしで 'bar'を挿入できます。私はここで何が欠けていますか?ForeignKeyにもかかわらず無効な値が挿入される

from sqlalchemy import create_engine, MetaData, Table, Column, Unicode, ForeignKey 

engine = create_engine(r'sqlite:///XXXXXXX.db', echo=True) 
metadata = MetaData() 
t1 = Table('t1', metadata, 
      Column('a', Unicode(), primary_key=True), 
      Column('b', Unicode(), ForeignKey('t2.c'))) 
t2 = Table('t2', metadata, 
      Column('c', Unicode(), primary_key=True)) 
metadata.create_all(engine) 
conn = engine.connect() 
conn.execute(t2.insert().values(c='first')) 
conn.execute(t2.insert().values(c='second')) 
conn.execute(t1.insert().values(a='foo', b='bar')) 
+0

場合によっては、[外部キーのサポートを有効にする](https://sqlite.org/foreignkeys.html)があることを確認してください。 –

+0

[件名に関するSQLAドキュメント](http://docs.sqlalchemy.org/en/latest/dialects/sqlite.html#foreign-key-support)をお読みください。いくつかの前提条件があり、使用前に新しい接続ごとに 'PRAGMA foreign_keys = ON'を発行する必要があります。 –

+0

ありがとう、私はSQLAのドキュメントからコードの一部をコピーし、私の驚きには魅力的なように働いた。私は私の驚きに言う。なぜなら、私は初心者で、私は以前はイベントを使用していなかったからだ。私が実際に理解していない部分は、set_sqlite_pragma関数がどのように機能するかです。それは何の議論ですか、彼らはどこから来たのですか? – user3087386

答えて

2

ありがとうございました。私は次のようにコードを修正しました。そして、期待通りに動作しています。これは、最後の行でIntegrityErrorを発生させています。

from sqlalchemy import create_engine, MetaData, Table, Column, Unicode, ForeignKey 
from sqlalchemy.engine import Engine 
from sqlalchemy import event 


@event.listens_for(Engine, "connect") 
def set_sqlite_pragma(dbapi_connection, connection_record): 
    cursor = dbapi_connection.cursor() 
    cursor.execute("PRAGMA foreign_keys=ON") 
    cursor.close() 

engine = create_engine(r'sqlite:///XXXXXXX.db', echo=True) 
metadata = MetaData() 
t1 = Table('t1', metadata, 
      Column('a', Unicode(), primary_key=True), 
      Column('b', Unicode(), ForeignKey('t2.c'))) 
t2 = Table('t2', metadata, 
      Column('c', Unicode(), primary_key=True)) 
metadata.create_all(engine) 
conn = engine.connect() 
conn.execute(t2.insert().values(c='first')) 
conn.execute(t2.insert().values(c='second')) 
conn.execute(t1.insert().values(a='foo', b='bar')) 
関連する問題