【问题标题】:sqlalchemy map entire table into attribute with classical mappingsqlalchemy 使用经典映射将整个表映射为属性
【发布时间】:2021-11-06 00:52:51
【问题描述】:

给定以下类和数据库表

class Location:
    datacenter_name: str
    path: str

locations = Table(
    "locations",
    mapper_registry.metadata,
    Column("id", Integer, primary_key=True, autoincrement=True),
    Column("path", String, nullable=False),
    Column("datacenter_name", String, nullable=False),
)
mapper_registry.map_imperatively(Location, locations)

backup_registry = Table(
    "backup_registry",
    mapper_registry.metadata,
    Column("id", Integer, primary_key=True, autoincrement=True),
    Column("source_location_id", ForeignKey("locations.id"), nullable=False),
    Column("backup_location_id", ForeignKey("locations.id"), nullable=False),
)

我想将 backup_registry 表映射到 BackupRegistry 实例,但我需要 将所有行映射到单个属性,例如:

class BackupRegistry:
    backups: Dict[Location, list[Location]]

使用与 location 相同的方法会给我一个 BackupRegistry 实例 每行mapper_registry.map_imperatively(BackupRegistry, backup_registry)

对如何通过经典映射实现这一点有任何想法吗?

【问题讨论】:

  • 我对注册表格式感到困惑。你能不能有类似location.backup_locations 的东西,它是给定location 的备份位置列表?

标签: python database sqlalchemy


【解决方案1】:

我不确定这种关系的内置解决方案是否不起作用或只是埋在文档中。


class Location:
    pass


locations = Table(
    "locations",
    mapper_registry.metadata,
    Column("id", Integer, primary_key=True, autoincrement=True),
    Column("path", String, nullable=False),
    Column("datacenter_name", String, nullable=False),
)

backup_registry = Table(
    "backup_registry",
    mapper_registry.metadata,
    Column("id", Integer, primary_key=True, autoincrement=True),
    Column("source_location_id", ForeignKey("locations.id"), nullable=False),
    Column("backup_location_id", ForeignKey("locations.id"), nullable=False),
)

mapper_registry.map_imperatively(Location, locations, properties={
    'backup_locations': relationship(Location,
                                     primaryjoin=locations.c.id == backup_registry.c.source_location_id,
                                     secondary=backup_registry,
                                     secondaryjoin=locations.c.id == backup_registry.c.backup_location_id,
                                     backref='source_locations',
    ),
})

然后可以从Location 访问backup_locations,例如location.backup_locations,这将是list()Locations。

这在self-referential-many-to-many-relationship 的文档中有记录。

【讨论】:

  • 这个想法是将处理备份的责任转移到与位置不同的另一个类中,因为需要所有可用备份的“全局”知识。该类应该知道从位置到备份的所有可用映射。不过感谢您的回答,我想我最终会使用 sqlalchemy 核心,因为我没有看到任何我想要的 ORM 实现
猜你喜欢
  • 2013-09-19
  • 1970-01-01
  • 2017-10-26
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
  • 2022-10-02
  • 1970-01-01
  • 2021-04-02
相关资源
最近更新 更多