2017-10-27 5 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'))