python - 尝试通过 SQLAlchemy 重新使用主键 ID 时出现问题

标签 python postgresql sqlalchemy

我正在尝试使用 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

我研究了级联并尝试了各种选项(全部、保存更新等)但没有效果。

任何指出我哪里出错的信息都将不胜感激,

谢谢,

克里斯

最佳答案

要解决您看到的错误,您可以更新与该用户 关联的所有DeviceInventory 模型上的外键> 提交前的模型。您必须确保您的 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/

相关文章:

python - 如何/在何处存储云应用程序的临时文件和日志?

python - 如何改进 Python C Extensions 文件行读取?

java - Spring Data PostgreSQL Key already exists 错误

sql - 递归查询中的排序结果

python - SQLAlchemy 在查询中获取子字符串

python - 将 Access 查询转换为 Python 脚本

Python 类型错误 : unsupported operand type(s) for +: 'NoneType' and 'str'

sql - 测试范围内的值

python - 使用 Nginx 和 uWsgi 的 Cherrypy 项目中的 SQLAlchemy 出现 UnboundExecutionError

python - SQLAlchemy 属性错误 : 'NoneType' object has no attribute '_getter'