【问题标题】:Why (and how ?) does sqlalchemy bypass FK constrainsts with sqlite? [duplicate]为什么(以及如何?)sqlalchemy 使用 sqlite 绕过 FK 约束? [复制]
【发布时间】:2018-06-03 15:39:33
【问题描述】:

在进行单元测试时,我写了一些我知道由于外部约束而不会通过的代码......但它确实通过了。

这是一个例子:

import os
import sqlalchemy as sa
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base, declared_attr
import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

try:
  os.unlink('test.db')
except:
  pass
engine = create_engine('sqlite:///test.db')

Base = declarative_base()

class Test1(Base):
  __tablename__ = 'Test1'
  id = sa.Column(sa.Integer(), primary_key = True)

class Test2(Base):
  __tablename__ = 'Test2'
  id = sa.Column(sa.Integer(), primary_key = True)
  link = sa.Column(sa.Integer(), sa.ForeignKey(Test1.id), index = True)

Base.metadata.create_all(engine)

Session = sessionmaker()

session = Session(bind=engine)

session.add(Test2(id=1, link=2)) # <-- should raise an error because 2 not in Test1
session.commit()
session.add(Test1(id=1))
session.commit()
session.add(Test2(id=2, link=1)) #ok
session.commit()
session.add(Test2(id=3, link=42)) # <-- should raise an error because 42 not in Test1
session.commit()

我声明了一个简单的数据库,一个表Test1 带有一个PK id,第二个表Test2 带有一个PK id 和一个Test2.link 上的FK 约束来引用Test1.id。然后,我插入一些会破坏 FK 的值。

FK 似乎可以工作,因为如果我打开一个 sqlite db 浏览器,我无法输入这些相同的值...

sqlalchemy 为什么以及如何绕过 FK?

注意:我还没有尝试过其他数据库

【问题讨论】:

    标签: python sqlite sqlalchemy


    【解决方案1】:

    您是否在 SQLite 中启用了强制执行功能?

    > PRAGMA foreign_keys = ON;
    

    related question。要在代码中启用此功能,可以使用

    engine = create_engine(database_url)
    engine.execute('PRAGMA foreign_keys=ON')
    

    这个other answer 有一个使用监听器/事件在连接时运行它的示例。

    def _fk_pragma_on_connect(dbapi_con, con_record):
        dbapi_con.execute('PRAGMA foreign_keys=ON')
    
    from sqlalchemy import event
    event.listen(engine, 'connect', _fk_pragma_on_connect)
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-06
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    相关资源
    最近更新 更多