我正在尝试使用 SQLAlchemy 在我的一个表中重用主键,但出现外键约束错误。
简而言之:
- PostgreSQL 8.4
- python 2.7
- SQLAlchemy 0.7
我有 3 个表:用户、库存和设备。 Inventories 和 Devices 与 User 具有一对一的关系。 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(出于安全和内部测试原因,它是唯一允许在代码中调用 reset 方法的记录)
>>>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>
) 仍然从表“设备”(或“库存”)中引用,其中 <id>
是重新分配为 id 1 之前的 newUser.id
我研究了级联并尝试了各种选项(全部、保存更新等)但没有效果。
任何指出我哪里出错的信息都将不胜感激,
谢谢,
克里斯
最佳答案
要解决您看到的错误,您可以更新与该用户
关联的所有Device
和Inventory
模型上的外键> 提交前的模型。您必须确保您的 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
上使用一个序列(就像在第二个模型声明中一样),并在用户表上添加另一个字段来指示用户是否是管理员(出于安全考虑)/您提到的测试目的)。这样您就不必依赖应用程序中的魔数(Magic Number)(例如,用户 ID)来实现应用程序逻辑,尤其是安全性。
关于python - 尝试通过 SQLAlchemy 重新使用主键 ID 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6157824/