更新-下面的解决方案
我对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)
我遇到了类似的情况,其中SQLAlchemy查询对象.all()不会返回表中的所有行(总是缺少某些行),但是.count()调用确实给出了正确的计数。在深入研究之后,我意识到模型声明与该数据库中的实际表模式有所不同。首先,数据库在模式中只有一个主键列,但是模型声明中有一个组成主键(与您的情况相反),我也错过了一个3列唯一约束,就像表模式一样。
在我的案例中发生的事情是,每当SQL Alchemy查询数据库时,它的确捕获了所有行,但是由于我的模型声明中的组成主键不正确,阻止了某些行加载到SQLAlchemy的会话中(根据定义,主键唯一地标识了这些对象,因此不会在会话中加载具有相同主键的两个对象,因此,即使在数据库中它们具有不同的PK,它也会丢弃具有相同值的那些组合列。)
总之,使用数据库模式进行双重检查模型声明以确保它们是同步的,这是此类问题的第一个响应。