尽管是ForeignKey

时间:2017-10-27 12:49:15

标签: python sqlalchemy

在下面的代码中,为什么插入表t1时没有错误? t1中的b列是外键,因此它只应接受t2中c列的值,但不知怎的,我可以插入' bar'没有错误。我在这里缺少什么?

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'))

修改

我不认为这个问题应该标记为链接的副本。关联的问题是关于如何强制执行外键,假设您已经知道默认情况下它没有打开。在我的问题中,我观察到一个奇怪的行为(违反外键约束)并要求根本原因。

1 个答案:

答案 0 :(得分:2)

感谢Ilja推进正确的方向。我按照以下方式修改了代码,现在它按预期工作,即在最后一行引发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'))
相关问题