【问题标题】:Foreign Key to Same Table in sqlalchemysqlalchemy 中同一表的外键
【发布时间】:2016-01-15 01:22:23
【问题描述】:

我有一个 MySQL 表,在 sqlalchemy 中定义,结构如下:

class User(Base):
    __tablename__ = 'user'
    __table_args__ = {'mysql_charset': 'utf8', 'mysql_engine': 'InnoDB'}
    id = Column(Integer, primary_key=True)
    handle = Column(String(250), nullable=False)
    owned = Column(Boolean(), default=False)
    owner_id = Column(Integer, ForeignKey("user.id"), nullable=True, default=null )
    current_price = Column(Integer, nullable=False, default=1)
    balance = Column(Integer, nullable=False, default=0)

我想要一个关系,以便 owner_id 可以为 null,或者如果已设置,它必须引用同一个表中的有效 user.id。

我不太了解 sqlalchemy 关系的东西,无法做到这一点。此页面顶部的特殊内容http://docs.sqlalchemy.org/en/latest/orm/relationship_persistence.html 似乎表明这是可能的,但我无法弄清楚。

然后我希望能够添加以下用户:

u1 = User(handle="bob")
u2 = User(handle="jim", owner=u1)

感谢您的帮助!

我应该补充一点,sqlalchemy 使用正确的 FOREIGN KEY 约束执行 CREATE TABLE 没有问题,并且我可以手动将数据插入到遵守规则的表中,因为我希望它们在 MySQL 中,它只使用失败的 sqlalchemy 模型.

编辑:已解决

owner_id 上的“default=null”由于某种原因导致了问题。有用的文档在这里:http://docs.sqlalchemy.org/en/rel_1_0/orm/self_referential.html 和来自该页面的代码示例:http://docs.sqlalchemy.org/en/rel_1_0/orm/examples.html#examples-adjacencylist

对于谷歌蜘蛛机器人,我在这个过程中遇到的错误是:

sqlalchemy.exc.IntegrityError: (_mysql_exceptions.IntegrityError) (1452, 'Cannot add or update a child row: a foreign key constraint fails (`twitfriends`.`tree`, CONSTRAINT `tree_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `tree` (`id`))') [SQL: u'INSERT INTO tree (parent_id, name) VALUES (%s, %s)'] [parameters: (<sqlalchemy.sql.elements.Null object at 0x7fe7e8c468d0>, 'rootnode')]

ArgumentError: Node.next and back-reference Node.prev are both of the same direction <symbol 'ONETOMANY>.  Did you mean to set remote_side on the many-to-one side ?

【问题讨论】:

  • 对于任何发现此问题的人来说,阻止上述代码工作的是 owner_id 字段上的 'default=null'!
  • 错误是:它产生了错误:sqlalchemy.exc.IntegrityError: (_mysql_exceptions.IntegrityError) (1452, '无法添加或更新子行:外键约束失败 (db. tree,约束 tree_ibfk_1 外键 (parent_id) 引用 tree (id))') [SQL: u'INSERT INTO tree (parent_id, name) VALUES (%s, %s)'] [参数:(, 'rootnode')]

标签: python mysql sqlalchemy


【解决方案1】:

由于User 只有一个外键,我希望 sqlalchemy 能够自动找出连接条件。您还可以添加backref,这样您就可以获得关系的另一方。

class User(Base):
    ...
    owner = relationship('User', remote_side=['id'], backref='owned_users')

Docs

例如

u1 = User(handle="bob")
u2 = User(handle="jim", owner=u1)
print u2.owned_users[0] == u1
# True

【讨论】:

  • 这两个都失败了: sqlalchemy.exc.ArgumentError: User.owner 和反向引用 User.owned_users 都是相同的方向符号('ONETOMANY')。您的意思是在多对一方面设置 remote_side 吗?
  • 这导致我这样做,但它似乎也不起作用:stackoverflow.com/questions/12872873/…
  • 谢谢.. 指向自引用页面的 URL 很有用,但有趣的是那里的示例都不适用于我。任何想法为什么?我有 SQLalchemy 1.0.11(从 pip 安装)和 MySQL,使用 InnoDB
  • 好吧,我不知道为什么,但这里的例子有效:docs.sqlalchemy.org/en/rel_1_0/_modules/examples/adjacency_list/… 我会看看我是否能找出原因并发布更新。感谢@Brendan 的链接!
猜你喜欢
  • 2013-06-03
  • 2021-07-02
  • 2017-11-10
  • 2012-03-02
  • 2015-02-24
  • 2019-11-24
  • 1970-01-01
  • 2014-04-16
  • 1970-01-01
相关资源
最近更新 更多