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

时间:2016-07-21 05:08:42

标签: mysql sqlalchemy

更新 - 解决方案

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

只返回1个结果应该是数百个

do { try NSFileManager.defaultManager().setAttributes
    ([NSFileExtensionHidden: NSNumber(bool: true)], ofItemAtPath: saveDialog.URL!.path!) } 

catch _{ Swift.print("Unable to hide extension") }

结果如下: 1

返回所有结果

for row in edb_alchemy.session.query(FtSite).filter(FtSite.serial_si == 200134444):
        print(row.s_sequence)

结果如下: (1) (2) (3) (4)...

返回FtSite表的1个结果和列

的所有结果
for row in edb_alchemy.session.query(FtSite.s_sequence).filter(FtSite.serial_si == 200134444):
        print(row)

结果如下 (1,1),(1,2),(1,3),(1,4)....

SQLAlchemy说它使用的SQL是

for row in edb_alchemy.session.query(FtSite, FtSite.s_sequence).filter(FtSite.serial_si == 200134444):
        print(row.FtSite.s_sequence, row.s_sequence)

正如我在SQLAlchemy之外使用SQL查询所期望的那样工作正常。

更新

感谢Ilja的评论。 出于某种原因,我认为这个表有一个id主键。 它没有,我只是这个数据库的消费者,应该更加敏锐。 你是对的。此表没有唯一键,并在FtSite.serial_si下列出MUL。

这就是表格的实际情况。

"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"

我原来的表格描述是

+------------+----------+------+-----+---------+----------------+
| 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    |                |
+------------+----------+------+-----+---------+----------------+

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

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)

2 个答案:

答案 0 :(得分:4)

我遇到了类似的情况,其中SQLAlchemy查询对象.all()没有返回表中的所有行(总是丢失一些),但.count()调用确实给出了正确的计数。在深入研究之后,我意识到模型声明偏离了该数据库中的实际表模式。首先,数据库在模式中有一个主键列,但模型声明有一个组合主键(与你的情况相反),我也错过了一个3列唯一约束,其中表模式具有它。

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

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

答案 1 :(得分:0)

是的,无论Devy提到什么都是正确的。我遇到了同样的问题,并且得到解决。请检查SQLAlchemy模型声明和数据库架构。如果您想使用“ Sqlacodegen”快速检查一下

sqlacodegen --outfile models.py mysql+pymysql://<username><password>@<hostname/ip of database>:<dbport>/<databasename>

https://pypi.org/project/sqlacodegen/(有关更多信息,请检查此)。

请告诉我是否需要任何东西。