Python SQLAlchemy:多个表和联接,重复行

Python SQLAlchemy:多个表和联接,重复行,python,join,sqlalchemy,duplicates,multiple-tables,Python,Join,Sqlalchemy,Duplicates,Multiple Tables,[我觉得这可能/肯定是重复的(?)但是,我整天都在寻找解决方案,似乎我自己无法让它以我想要的方式工作。] 在MySQL中,我有三个表,分别命名为ecordov(A)、ecordovadr(B)和ecrgposvk(C)。 我有一把钥匙把所有这些联系起来;在(A)中,每个键有一行,在(B)和(C)中,每个键可能有多行,因此,如果不是这些问题的专家,我认为这是一对多的关系 我已经阅读了SQLAlchemy文档,并按照如下方式设置了我的表格: class Ecordov(Base): __t

[我觉得这可能/肯定是重复的(?)但是,我整天都在寻找解决方案,似乎我自己无法让它以我想要的方式工作。]

在MySQL中,我有三个表,分别命名为ecordov(A)、ecordovadr(B)和ecrgposvk(C)。 我有一把钥匙把所有这些联系起来;在(A)中,每个键有一行,在(B)和(C)中,每个键可能有多行,因此,如果不是这些问题的专家,我认为这是一对多的关系

我已经阅读了SQLAlchemy文档,并按照如下方式设置了我的表格:

class Ecordov(Base):

    __tablename__ = 'ecordov'

    oovkey = Column(BIGINT, primary_key=True)
    oovorder = Column(BIGINT)
    ecordovadr = relationship('Ecordovadr')
    ecrgposvk = relationship('Ecrgposvk')


class Ecordovadr(Base):

    __tablename__ = 'ecordovadr'

    ooakey = Column(BIGINT, primary_key=True)
    ooaname1 = Column(VARCHAR)
    ooaorder = Column(BIGINT, ForeignKey('ecordov.oovorder'))


class Ecrgposvk(Base):

   __tablename__ = 'ecrgposvk'

   rgkey = Column(BIGINT, primary_key=True)
   rgposvalue = Column(DOUBLE)
   rgposordnum = Column(BIGINT, ForeignKey('ecordov.oovorder'))
[因此,正如您所看到的,
外键
不是
主键
,不确定这是否是一个问题?但是,我无法更改数据库的结构。]

我的示例查询如下所示:

jobs = session.query(Ecordov, func.group_concat(Ecordovadr.ooaname1.op('ORDER BY')(text('ecordovadr.ooatype, ecordovadr.ooarank separator "{}"'))).label('ooaname1')).outerjoin(Ecordovadr).filter(Ecordov.oovorder.like('75289')).group_by(Ecordov.oovorder)
计算结果为:

SELECT ecordov.oovkey AS ecordov_oovkey, ecordov.oovorder AS ecordov_oovorder, group_concat(ecordovadr.ooaname1 ORDER BY ecordovadr.ooatype, ecordovadr.ooarank separator "{}") AS ooaname1 
FROM ecordov LEFT OUTER JOIN ecordovadr ON ecordov.oovorder = ecordovadr.ooaorder 
WHERE ecordov.oovorder LIKE '75289'
GROUP BY ecordov.oovorder
SELECT ecordov.oovkey AS ecordov_oovkey, ecordov.oovorder AS ecordov_oovorder, group_concat(ecordovadr.ooaname1 ORDER BY ecordovadr.ooatype, ecordovadr.ooarank separator "{}") AS ooaname1 
FROM ecordov LEFT OUTER JOIN ecordovadr ON ecordov.oovorder = ecordovadr.ooaorder LEFT OUTER JOIN ecrgposvk ON ecordov.oovorder = ecrgposvk.rgposordnum 
WHERE ecordov.oovorder LIKE '75289'
GROUP BY ecordov.oovorder
并给了我以下信息:

for x in jobs:
    x.ooaname1

u'Sorbe priv.{}Lebensn\xe4he GmbH'
这是我想要的结果

但是,在连接第二个表之后,无论是使用内部连接还是外部连接,例如,通过以下方式:

jobs = session.query(Ecordov, func.group_concat(Ecordovadr.ooaname1.op('ORDER BY')(text('ecordovadr.ooatype, ecordovadr.ooarank separator "{}"'))).label('ooaname1')).outerjoin(Ecordovadr).outerjoin(Ecrgposvk).filter(Ecordov.oovorder.like('75289')).group_by(Ecordov.oovorder)
其计算结果如下:

SELECT ecordov.oovkey AS ecordov_oovkey, ecordov.oovorder AS ecordov_oovorder, group_concat(ecordovadr.ooaname1 ORDER BY ecordovadr.ooatype, ecordovadr.ooarank separator "{}") AS ooaname1 
FROM ecordov LEFT OUTER JOIN ecordovadr ON ecordov.oovorder = ecordovadr.ooaorder 
WHERE ecordov.oovorder LIKE '75289'
GROUP BY ecordov.oovorder
SELECT ecordov.oovkey AS ecordov_oovkey, ecordov.oovorder AS ecordov_oovorder, group_concat(ecordovadr.ooaname1 ORDER BY ecordovadr.ooatype, ecordovadr.ooarank separator "{}") AS ooaname1 
FROM ecordov LEFT OUTER JOIN ecordovadr ON ecordov.oovorder = ecordovadr.ooaorder LEFT OUTER JOIN ecrgposvk ON ecordov.oovorder = ecrgposvk.rgposordnum 
WHERE ecordov.oovorder LIKE '75289'
GROUP BY ecordov.oovorder
给我:

for x in jobs:
    x.ooaname1

u'Sorbe priv.{}Sorbe priv.{}Sorbe priv.{}Lebensn\xe4he GmbH{}Lebensn\xe4he GmbH{}Lebensn\xe4he GmbH'
因此,数据现在增加了三倍。我在其他关于这个主题的帖子中读到,这是意料之中的,特别是当对多个表使用相同的
ForeignKey

但我需要“像以前一样”的数据,这意味着只有一个条目,而不是三个条目。我尝试过使用distinct(),但到目前为止没有成功

有人能告诉我一个方向吗,怎么解决这个问题


提前感谢,祝你一切顺利

您在哪里尝试使用了
distinct
?您是否尝试过
…group_concat(Ecordovard.ooaname1.distinct().op(…)…)
?嗨,范,非常感谢您的评论!你描述的方式确实有效。我在查询的最后使用了.distinct(all)。然而,在我的特定情况下,我刚刚意识到,使用.distinct()会得到错误的结果,因为在某些情况下,分组行的不同位置可能有相同的名称。所讨论的工作是关于提货和送货,有些工作确实包括同一家公司两次,例如,如果你在他们的地方提货,去另一个地方,然后回到起点。我现在通过使用两个查询找到了一个解决方法,这可能不是。。。。。。但是,我认为,从最佳性能角度来看,没有不同的解决方案。如果这不是真的,就给我一个提示。再次感谢!尽管如此,我还是想知道如何正确地解决这个问题…只是想一下,显式地选择主键并对其使用.distinct()?我不认为我理解这3个表的作用,名称对我没有帮助(我想它们对你来说没问题!!)。有几个问题,
oovorder
是否唯一,即使它不是主键<代码>oovkey将是一个“技术”pk,而
oovorder
将是功能性pk?对于您正在发布的示例,
ecordov.oovorder LIKE'75289'
,3个表中的每个表中有多少个寄存器?您在哪里尝试使用了
distinct
?您是否尝试过
…group_concat(Ecordovard.ooaname1.distinct().op(…)…)
?嗨,范,非常感谢您的评论!你描述的方式确实有效。我在查询的最后使用了.distinct(all)。然而,在我的特定情况下,我刚刚意识到,使用.distinct()会得到错误的结果,因为在某些情况下,分组行的不同位置可能有相同的名称。所讨论的工作是关于提货和送货,有些工作确实包括同一家公司两次,例如,如果你在他们的地方提货,去另一个地方,然后回到起点。我现在通过使用两个查询找到了一个解决方法,这可能不是。。。。。。但是,我认为,从最佳性能角度来看,没有不同的解决方案。如果这不是真的,就给我一个提示。再次感谢!尽管如此,我还是想知道如何正确地解决这个问题…只是想一下,显式地选择主键并对其使用.distinct()?我不认为我理解这3个表的作用,名称对我没有帮助(我想它们对你来说没问题!!)。有几个问题,
oovorder
是否唯一,即使它不是主键<代码>oovkey将是一个“技术”pk,而
oovorder
将是功能性pk?对于您正在发布的示例,
ecordov.oovorder LIKE'75289'
,3个表中的每个表中有多少个寄存器?