SQLAlchemy 不使用 ForeignKey 如何进行关联?

2017-10-06 21:24:57 +08:00
 cevincheung

官方文档

class Address(Base):
     __tablename__ = 'addresses'
     id = Column(Integer, primary_key=True)
     email_address = Column(String, nullable=False)
     user_id = Column(Integer, ForeignKey('users.id'))

     user = relationship("User", back_populates="addresses")

     def __repr__(self):
         return "<Address(email_address='%s')>" % self.email_address

这里 ForeignKey('users.id') 是必须的么? 可以不使用外键强制约束吗?

3215 次点击
所在节点    Python
6 条回复
linnchord
2017-10-06 23:11:42 +08:00
可以啊,自己写程序实现关联呗。
Tyanboot
2017-10-07 01:20:03 +08:00
当然可以啦, 比如说你有一个 users 表:

class User(Base):
__tablename__ = "users"
id_ = Column(Integer, primary_key=True)
name = Column(String(16))

你还有一个 address 表:

class Address(Base):
__tablename__ = "address"
id_ = Column(Integer, primary_key=True)
place = Column(String(256))
user_id = Column(Integer)

user = relationship("User", uselist=False, primaryjoin=foreign(user_id) == remote(User.id_))

你只需要在 relationship 里用 primaryjoin 来手动指定 join 关系就可以了, 前提是已经导入了 User. 这部分也在文档里提到了

此外还可以写成

relationship("User", uselist=False, foreign_keys=user_id, primaryjoin="Address.user_id==User.id_")

这种写法同样要求已经导入 User, 但是会被 ide 识别为 unused import. 所以建议使用第一种
cevincheung
2017-10-07 18:34:27 +08:00
@Tyanboot #2
user = relationship("User", uselist=False, primaryjoin=foreign(user_id) == remote(User.id_))

这不还是有 foreign 么
Tyanboot
2017-10-08 01:04:03 +08:00
@cevincheung …首先你是不是被降权了,没收到通知

其次虽然这里有 foreign,但实际上在数据库里面是不会有外键约束的。这里只是把这个 user_id 看作了外键,以便于进行 join 查询,和他本身是不是外键是没关系的。
cevincheung
2017-10-08 08:18:48 +08:00
@Tyanboot #4
好像是吧……

表示在 sqlalchemy 里并没有 foreign 和 remote 两个方法

no named module
cevincheung
2017-10-08 08:20:25 +08:00
@Tyanboot #4
好吧,在 sqlalchemy.orm 中

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/395687

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX