【问题标题】:Return the Table whose primary key is another table's foreign key, SQL Alchemy返回主键是另一个表的外键的表,SQL Alchemy
【发布时间】:2021-11-20 22:12:49
【问题描述】:

我可以返回外键引用的表的名称,但我想做相反的事情。

假设我有两个表,Users 和 Address,Address 对 Users 有一个外键(一对多)。我也做了这个双向的,这样我就可以从地址表中获取用户。

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    address = relationship("Address", back_populates="user")


class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True, autoincrement=True)
    company_name = Column(String)
    user_id = Column(Integer, ForeignKey('user.id'))
    user = relationship("User", back_populates="address")

如果我想找出父表的名称,以一种适用于类似关系的任何其他表的方式,我可以这样做:

for i in Address.__table__.foreign_key_constraints:
   print(i.referred_table)

tab = Table(Address.__tablename__, Base.metadata, autoload_with=engine, extend_existing=True)

for i in tab.foreign_key_constraints:
      print(i.referred_table)
#both output "user" which is the __tablename__ of User

这是我使用外键约束属性访问用户表。但是我该如何做相反的事情,使用来自用户的属性来访问地址?我主要想知道这样我就可以处理批量核心插入中的关系。

tab = Table(User.__tablename__, Base.metadata, autoload_with=engine, extend_existing=True)

records = df.to_dict(orient="records")
insert_stmt = sqlalchemy.dialects.sqlite.insert(tab).values(records)
#list of primary keys
pks = [pk.name for pk in tab.primary_key]
update_columns = {col.name: col for col in insert_stmt.excluded if col.name not in pks}
update_statement = insert_stmt.on_conflict_do_update(index_elements=pks, set_=update_columns)

一旦我执行了 on_conflict_do_update 语句,上述方法就可以工作,但它不会生成任何地址行。

【问题讨论】:

  • 您想要所有引用给定表键的表吗?
  • @Shawn 有点像。我想要所有将我的表的主键作为外键的表。就我而言,它只是一个。具体来说,它类似于使用我的用户表中的某些属性/方法返回地址表。目前我只知道如何将用户表作为地址表的属性返回

标签: python sqlite sqlalchemy


【解决方案1】:

我找到了一种方法,但它不像我想要的那样干净。

tab = list(inspect(User).relationships)[0].entity.local_table

对于任何声明性表(类),您可以检查它们以获取 Mapper 对象。 Mapper 对象具有关系作为属性,它返回关系的集合。

inspect(User).relationships
#Get the relationship, note this will return the relationship attribute from the class
list(inspect(User).relationships)[0]

然后我使用 .entity 获取此关系所属的映射器/类。然后从声明性表中返回一个带有local_table属性的表对象

entity = list(inspect(User).relationships)[0].entity
tab = entity.local_table

此语句的计算结果应为 True

tab == Address.__table__

【讨论】:

    猜你喜欢
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    相关资源
    最近更新 更多