SQLAlchemy - 最新的多对多关系
SQLAlchemy - Latest of many to many relationship
我目前正在构建一个 API(使用 SQLAlchemy、FastAPI 和 Pydantic)来存储有关公寓及其居民的信息。一间公寓一次只能由一位居民入住,但我们会存储历史记录。数据模型如下:
class Resident(Base):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False)
name = Column(String(200))
class Apartment(Base):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False)
address = Column(String(200))
residents = relationship("Occupation")
class Occupation(Base):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False)
start = Column(Date)
end = Column(Date)
resident_id = Column(UUID(as_uuid=True), ForeignKey("residents.id"))
resident = relationship("Resident")
apartment_id = Column(UUID(as_uuid=True), ForeignKey("apartments.id"))
apartment = relationship("Apartment")
公寓的 'residents' 关系将给我一个与职业的 1-N 关系。但我想要的是一种关系,它以 1-1 的方式为我提供给定公寓的当前居民。
以下查询用于获取所有公寓和业主:
db.query(models.Apartment).options(
joinedload(models.Apartment.residents).joinedload(models.Occupation.resident),
).all()
使用 Pydantic 模式,这转化为以下 JSON:
[
{
"id": "4c260b11-0b93-4e68-a931-5facfb6bac52",
"address": "X",
"residents": [
{
"start": "2021-01-01",
"end": "2021-12-31",
"resident": {
"id": "982f6398-5213-4b07-8187-2d5606ee4142",
"name": "Steve Jobs"
}
}
]
}
]
但我正在寻找的是:
[
{
"id": "4c260b11-0b93-4e68-a931-5facfb6bac52",
"address": "X",
"current_resident": {
"id": "982f6398-5213-4b07-8187-2d5606ee4142",
"name": "Steve Jobs"
}
}
]
是否有 SQLAlchemy 方法可以实现此目的?
您可以做的是向 Apartment
添加一个额外的 viewonly
关系,您在其中过滤当前日期:
today = datetime.date.today().strftime('%Y-%m-%d')
current_resident = relationship("Resident",
secondary="occupation",
primaryjoin=f'and_(Occupation.apartment_id == Apartment.id, \
Occupation.start <= "{today}", \
Occupation.end > "{today}")',
secondaryjoin="Occupation.resident_id == Resident.id",
uselist=False,
viewonly=True
)
此returns当前居住者的Resident
对象或None
当前日期没有居住者
我目前正在构建一个 API(使用 SQLAlchemy、FastAPI 和 Pydantic)来存储有关公寓及其居民的信息。一间公寓一次只能由一位居民入住,但我们会存储历史记录。数据模型如下:
class Resident(Base):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False)
name = Column(String(200))
class Apartment(Base):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False)
address = Column(String(200))
residents = relationship("Occupation")
class Occupation(Base):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False)
start = Column(Date)
end = Column(Date)
resident_id = Column(UUID(as_uuid=True), ForeignKey("residents.id"))
resident = relationship("Resident")
apartment_id = Column(UUID(as_uuid=True), ForeignKey("apartments.id"))
apartment = relationship("Apartment")
公寓的 'residents' 关系将给我一个与职业的 1-N 关系。但我想要的是一种关系,它以 1-1 的方式为我提供给定公寓的当前居民。
以下查询用于获取所有公寓和业主:
db.query(models.Apartment).options(
joinedload(models.Apartment.residents).joinedload(models.Occupation.resident),
).all()
使用 Pydantic 模式,这转化为以下 JSON:
[
{
"id": "4c260b11-0b93-4e68-a931-5facfb6bac52",
"address": "X",
"residents": [
{
"start": "2021-01-01",
"end": "2021-12-31",
"resident": {
"id": "982f6398-5213-4b07-8187-2d5606ee4142",
"name": "Steve Jobs"
}
}
]
}
]
但我正在寻找的是:
[
{
"id": "4c260b11-0b93-4e68-a931-5facfb6bac52",
"address": "X",
"current_resident": {
"id": "982f6398-5213-4b07-8187-2d5606ee4142",
"name": "Steve Jobs"
}
}
]
是否有 SQLAlchemy 方法可以实现此目的?
您可以做的是向 Apartment
添加一个额外的 viewonly
关系,您在其中过滤当前日期:
today = datetime.date.today().strftime('%Y-%m-%d')
current_resident = relationship("Resident",
secondary="occupation",
primaryjoin=f'and_(Occupation.apartment_id == Apartment.id, \
Occupation.start <= "{today}", \
Occupation.end > "{today}")',
secondaryjoin="Occupation.resident_id == Resident.id",
uselist=False,
viewonly=True
)
此returns当前居住者的Resident
对象或None
当前日期没有居住者