SQLAlchemy,在使用子查询时,count返回的数字与Python的len()函数不同

时间:2017-02-05 21:58:03

标签: python sqlalchemy

当使用多个子查询和其中一个子查询内部的连接时,似乎sqlalchemy的count()函数没有返回与python的len()函数相同的值。问题是,我一般都在做子查询错误,或者sqlalchemy中是否有错误或者这里发生了什么?在这种情况下,可以用SQL如何处理计数来解释这种行为吗?

以下完全正常的小型演示代码:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Boolean
from sqlalchemy.orm import sessionmaker

# creating a DB in memory, is removed when program stops
engine = create_engine('sqlite:///:memory:', echo=True)
engine.connect()

Base = declarative_base()

# tables
class TableA(Base):
    __tablename__ = 'table_a'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    foo = Column(Boolean)

class TableB(Base):
    __tablename__ = 'table_B'

    id = Column(Integer, primary_key=True)
    id_table_a = Column(Integer)
    bar = Column(Boolean)

# mapping
Base.metadata.create_all(engine)

# session
Session = sessionmaker(bind=engine)
s = Session()

# Test records
s.add(TableA(name='test_1', foo=True)) # relevant main
s.add(TableA(name='test_2', foo=True))
s.add(TableA(name='test_3', foo=False))

s.add(TableB(id_table_a=1, bar=False)) # relevant entry 1
s.add(TableB(id_table_a=1, bar=False)) # relevant entry 2
s.add(TableB(id_table_a=2, bar=True))

# sub queries
sub1 = s.query(TableA).filter(TableA.name == 'test_1').subquery()
sub2 = s.query(TableA).join(TableB, TableB.id_table_a == TableA.id).filter(TableB.bar == False).subquery()

sub_q = s.query(TableA).filter(
        TableA.id == sub1.c.id,
        TableA.id == sub2.c.id
    )

sub_count = sub_q.count()
sub_all = sub_q.all()

print "unrelevant count all: " + str(s.query(TableA).count())
print "sql count: " + str(sub_count)
print "python len: " + str(len(sub_all))
print sub_all
print sub_all[0].name

代码打印这些值:

unrelevant count all: 3
sql count: 2
python len: 1
[<__main__.TableA object at 0x0330FC90>]
test_1

正如你所看到的,count()返回值2,但如果我接受all()然后使用pythons len()函数将返回1.如果我不加入tableB,则计数工作正常,但是当加入时,只需从TableB记录中获取计数,如果连接条件匹配(即id_table_a == 1和bar == False)。

至少Postgres和sqlite会出现同样的问题。

0 个答案:

没有答案