til*_*151 7 sqlalchemy cartesian-product relationship composite-primary-key window-functions
假设我有以下数据库架构:
class A(Base):
__tablename__ = "a_table"
id = Column(Integer, primary_key=True, autoincrement=True)
version = Column(Integer, primary_key=True, default=1)
# More columns...
bs = relationship(
"B", secondary="a2b_table", back_populates="as"
)
class B(Base):
__tablename__ = "b_table"
id = Column(Integer, primary_key=True)
as = relationship(
A, secondary="a2b_table", back_populates="bs"
)
class A2B(Base):
__tablename__ = "a2b_table"
a_id = Column(
Integer(),
primary_key=True,
)
a_version = Column(
Integer,
primary_key=True,
)
b_id = sa.Column(
Integer,
ForeignKey("b.id", name="b_fk"),
primary_key=True,
)
__table_args__ = (
ForeignKeyConstraint(
[a_id, a_version],
[A.id, A.version],
name="a_fk",
),
{},
)
Run Code Online (Sandbox Code Playgroud)
每个A版本都由 标识,id并且可以有多个版本。如果 的列A(未显示的列)发生变化,我会生成一个A具有相同id和 的新列version+1。该关系bs为我提供了B与特定版本的A.
问题是,该关系as为我提供了A与特定B. 相反,我希望该关系仅包含每个 的最新(最高)版本A。按照文档,我尝试使用自定义函数primaryjoin和窗口函数来解决此问题:
partition = select(
A,
row_number()
.over(order_by=A.version.desc(), partition_by=A.id)
.label("index"),
).alias()
partitioned_as = aliased(A, partition)
B.latest_as = relationship(
partitioned_as,
primaryjoin=and_(
partition.c.index == 1,
and_(
partitioned_as.id == A2B.a_id,
partitioned_as.version == A2B.a_version,
),
),
secondary="a2b_table",
viewonly=True,
)
Run Code Online (Sandbox Code Playgroud)
不幸的是,它不起作用,我收到警告:
SELECT 语句在 FROM 元素“anon_1”、“a2b_table”和 FROM 元素“a_table”之间具有笛卡尔积。在每个元素之间应用连接条件以进行解析。
我检查了 sqlalchemy 生成的 SQL 语句,它的 FROM 子句中有 ,即,anon_1的查询。据我了解,不应该出现在该语句的 FROM 子句中,因为它已经位于 的 FROM 子句中。我不知道如何摆脱它。partitiona_tablea_tablepartition
有人能指出我正确的方向吗?提前致谢。
| 归档时间: |
|
| 查看次数: |
3645 次 |
| 最近记录: |