SqlAlchemy在查询表对象时不返回所有行,但是在查询表对象列时返回所有行

Jos*_*osh 2 mysql sqlalchemy

更新-下面的解决方案

我对SqlAlchemy非常陌生,因此如果这是一个明显的问题,请原谅。当查询Table对象时,我只会得到一个结果(数据库中的第一个结果,过滤器有600多个结果)。当我按表上的一列查询时,它将返回我期望的所有数据。我做错了什么?

仅返回1个结果应为数百

for row in edb_alchemy.session.query(FtSite).filter(FtSite.serial_si == 200134444):
        print(row.s_sequence)
Run Code Online (Sandbox Code Playgroud)

结果如下:1

返回所有结果

for row in edb_alchemy.session.query(FtSite.s_sequence).filter(FtSite.serial_si == 200134444):
        print(row)
Run Code Online (Sandbox Code Playgroud)

结果看起来像:(1,)(2,)(3,)(4,)...

为FtSite表返回1个结果,为列返回所有结果

for row in edb_alchemy.session.query(FtSite, FtSite.s_sequence).filter(FtSite.serial_si == 200134444):
        print(row.FtSite.s_sequence, row.s_sequence)
Run Code Online (Sandbox Code Playgroud)

结果看起来像(1,1),(1、2),(1、3),(1,4)....

SQLAlchemy说其使用的SQL是

"SELECT ft_site.serial_si AS ft_site_serial_si, ft_site.partition_id AS ft_site_partition_id, ft_site.s_sequence AS ft_site_s_sequence, ft_site.value AS ft_site_value" + \
    " FROM ft_site" + \
    " WHERE ft_site.serial_si = 200134444"
Run Code Online (Sandbox Code Playgroud)

仅在SQLAlchemy之外使用SQL查询时,该方法可以按我预期的那样正常工作。


更新资料

谢谢Ilja的评论。由于某种原因,我认为该表具有ID主键。事实并非如此,我只是这个数据库的使用者,应该更加谨慎。你说的没错。该表没有唯一键,并且在FtSite.serial_si下列出了MUL。

这就是表格的实际外观。

+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| p_id       | int(10)  | NO   |     | NULL    |                |
| serial_si  | int(10)  | NO   | MUL | NULL    |                |
| s_sequence | int(10)  | NO   |     | NULL    |                |
| value      | double   | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

我原来的表描述是

class FtSite(Base):
    __tablename__ = "ft_site"

    id = Column(INTEGER, primary_key=True)
    serial_si = Column(INTEGER)
    partition_id = Column(INTEGER)
    s_sequence = Column(INTEGER)
    value = Column(DOUBLE)
Run Code Online (Sandbox Code Playgroud)

我将其更改为在SQLAlchemy中具有复合键(s_sequence,serial_si)是唯一的,即使未在数据库中定义也是如此。这是在SQLAlchemy中处理此问题的最佳方法吗?现在正在返回预期结果。

class FtSite(Base):
    __tablename__ = "ft_site"

    serial_si = Column(INTEGER, primary_key=True)
    partition_id = Column(INTEGER)
    s_sequence = Column(INTEGER, primary_key=True)
    value = Column(DOUBLE)
Run Code Online (Sandbox Code Playgroud)

Dev*_*evy 6

我遇到了类似的情况,其中SQLAlchemy查询对象.all()不会返回表中的所有行(总是缺少某些行),但是.count()调用确实给出了正确的计数。在深入研究之后,我意识到模型声明与该数据库中的实际表模式有所不同。首先,数据库在模式中只有一个主键列,但是模型声明中有一个组成主键(与您的情况相反),我也错过了一个3列唯一约束,就像表模式一样。

在我的案例中发生的事情是,每当SQL Alchemy查询数据库时,它的确捕获了所有行,但是由于我的模型声明中的组成主键不正确,阻止了某些行加载到SQLAlchemy的会话中(根据定义,主键唯一地标识了这些对象,因此不会在会话中加载具有相同主键的两个对象,因此,即使在数据库中它们具有不同的PK,它也会丢弃具有相同值的那些组合列。)

总之,使用数据库模式进行双重检查模型声明以确保它们是同步的,这是此类问题的第一个响应。

  • 这也让我摆脱了一些非常困难的困惑。谢谢你!复制 SQLAlchemy 创建的查询直接在数据库中返回正确的结果。这意味着 SQLAlchemy 在查询数据库后会对结果添加更多逻辑。不确定我是否喜欢这样,但至少现在我知道了。 (2认同)