我正在尝试使用SQLAlchemy在我的一个表中重用主键,并且出现外键约束错误。
简而言之:
我有3个表:用户,库存和设备。库存和设备与用户具有一对一的关系。 User.id是Inventories.user_id和Devices.user_id外键。
我已经在模型中设置了用户,设备和库存/根据标准的python实践。
在交互式python中我可以发出以下命令没问题:
>>>newUser = User.create()
>>>newUser.device = User.create_device(<*args>)
>>>Session.add(newUser)
>>>Session.commit()
(在代码中自动创建库存记录)
现在,假设我想重新使用用户记录1(这是唯一允许在代码中出现安全和内部测试原因的重置方法的记录)
>>>oldUser = User.retrieve(1)
>>>Session.delete(oldUser)
>>>Session.commit()
(确认用户1不再存在)
>>>newUser = User.create()
>>>newUser.device = User.create_device(<*args>)
>>>newUser.id = 1
>>>Session.add(newUser)
>>>Session.commit()
此时我会得到一个错误,即Key(id)=(<id>
)仍然从表“devices”(或“inventoryories”)引用,其中<id>
是newUser。在重新分配为id 1之前的id
我已经考虑了级联,并尝试了各种选项(所有,保存更新等),但没有效果。
任何有关我出错的信息都会非常感激,
谢谢,
Krys
答案 0 :(得分:0)
要解决您看到的错误,您可以在提交之前更新与该Device
模型关联的所有Inventory
和User
模型上的外键。您必须确保您的User
模型不会自动增加id(即,它不是PostgreSQL序列)。
例如,SQLAlchemy模型声明应为
class User(base):
__tablename__ = 'user'
id = Column('id', Integer, primary_key=True, unique=True, nullable=False)
而不是
class User(base):
__tablename__ = 'user'
id = Column('id', Integer, Sequence('user_id_seq'), primary_key=True)
但是,这可能不是正确的方法!在User.id
上使用序列(如第二个模型声明中)更好的设计,并在用户表上添加另一个字段,指示用户是否为管理员(出于安全/测试的目的,您提到了)。这样,您就不必依赖应用程序中的幻数(例如,用户ID)来处理应用程序逻辑,尤其是安全性。
答案 1 :(得分:0)
我没有使用SQLAlchemy,所以我没有正确的答案,但我可以说你必须问自己你想要的是真的有必要吗?
由于,
首先,你必须决定它是否值得吗?
答案 2 :(得分:0)
由于这是生产中不应该出现的问题,只需使用SET CONSTRAINTS
即可。您可以在FOREIGN KEY
上使用INITIALLY DEFERRED
,但我不建议您这样做,因为您没有处理生产中存在的循环依赖。