gpt4 book ai didi

python - 以 SQLAlchemy 有效的方式处理一对多关系

转载 作者:行者123 更新时间:2023-12-01 04:43:18 24 4
gpt4 key购买 nike

我是一名 SQL 初学者。

我有一个包含三张表的数据库,表为“Person”,表为“Hotel”和“Apartment”。每个人仅与一间酒店或公寓有一种关系,但每间酒店或公寓可以分配一个或多个人。

具有以下架构:

class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True, nullable=False)
person_name = Column(String, nullable=False)
status = Column(String, nullable=False)

class Hotel(Base):
__tablename__ = 'hotel'
id = Column(Integer, primary_key=True, nullable=False)
hotel_name = Column(String, nullable=False)
hotel_address = Column(String)

person_id = Column(Integer, ForeignKey("person.id"), nullable=False)
person = relationship("Person", backref=backref("hotel", uselist=False))

class Apartment(Base):
__tablename__ = 'apartment'
id = Column(Integer, primary_key=True, nullable=False)
apartment_address = Column(String, nullable=False)

person_id = Column(Integer, ForeignKey("person.id"), nullable=False)
person = relationship("Person", backref=backref("apartment", uselist=False))

或者这个,每个酒店和公寓都有一个唯一的 key ,并过滤新的“ key ”列:

class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True, nullable=False)
person_name = Column(String, nullable=False)
status = Column(String, nullable=False)
key = Column(String, nullable=False)

class Hotel(Base):
__tablename__ = 'hotel'
id = Column(Integer, primary_key=True, nullable=False)
hotel_name = Column(String, nullable=False)
hotel_address = Column(String)
key = Column(String, nullable=False, unique=True)

class Apartment(Base):
__tablename__ = 'apartment'
id = Column(Integer, primary_key=True, nullable=False)
apartment_address = Column(String, nullable=False)
key = Column(String, nullable=False, unique=True)

当拥有唯一键时,酒店和公寓表中的“id”列是否不必要?

第二个问题是关于 Person 表中的这一列:

status = Column(String, nullable=False) 

我希望状态列只是(酒店、公寓)中的值之一,这将告诉您在酒店或公寓表中到底在哪里查找关系。

有什么想法吗?

最佳答案

在第一个示例中,HotelApartment 表中有 person_id 列,这意味着您将在 Hotel 中有单独的记录每个人的 Apartment 表,这似乎不是您想要做的。因此外键应移至 Person 表。因此,下一个问题是对两个表使用一个外键,这样您就不必进行繁琐的检查(例如在设置 Apartment_id 时检查 hotel_id 是否设置)。这可以使用 SqlAlchemy 的 polymorphic_identity 来完成。您可以阅读here 。在这种情况下,您的模型结构应如下所示:

class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True, nullable=False)
person_name = Column(String, nullable=False)

accommodation_id = Column(Integer, ForeignKey("accommodation.id"))
accommodation = relationship("Accommodation", backref="people")


class Accommodation(Base):
__tablename__ = 'accommodation'
__mapper_args__ = {
'polymorphic_identity':'accommodation',
# polymorphic_on determines the field that will have values like 'hotel' and 'apartment' depending on the table
'polymorphic_on': 'accommodation_type'
}

id = Column(Integer, primary_key=True)
accommodation_type = Column(String(32))
address = Column(String)


class Hotel(Accommodation):
__tablename__ = 'hotel'
__mapper_args__ = {
# all the records in this table will have accommodation_type = 'hotel'
'polymorphic_identity': 'hotel'
}

id = Column(Integer, ForeignKey('accommodation.id'), primary_key=True)
hotel_name = Column(String, nullable=False)


class Apartment(Accommodation):
__tablename__ = 'apartment'
__mapper_args__ = {
# all the records in this table will have accommodation_type = 'apartment'
'polymorphic_identity': 'apartment'
}

id = Column(Integer, ForeignKey('accommodation.id'), primary_key=True)

这样,您就有了基本模型 Accommodation,它的 id 链接到表 Hotel 中的 id 列> 和 Appartment,仅包含特定于它们的字段。 person.accommodation 将根据实际值返回酒店或公寓,并且父表和子表的所有属性都可用。这样您就可以确保一个人不会同时链接到酒店和公寓。您可以通过检查person.accommodation.accommodation_type来检查此人链接到的住宿类型。

关于python - 以 SQLAlchemy 有效的方式处理一对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30077066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com