Подтвердить что ты не робот

Как подсчитать строки с помощью SELECT COUNT (*) с помощью SQLAlchemy?

Я хотел бы знать, возможно ли сгенерировать оператор SELECT COUNT(*) FROM TABLE в SQLAlchemy без явного запроса его с помощью execute(). Если я использую:

session.query(table).count()

то он генерирует что-то вроде:

SELECT count(*) AS count_1 FROM
    (SELECT table.col1 as col1, table.col2 as col2, ... from table)

который значительно медленнее в MySQL с InnoDB. Я ищу решение, которое не требует, чтобы таблица имела известный первичный ключ, как предложено в Получить количество строк в таблице, используя SQLAlchemy.

4b9b3361

Ответ 1

Мне удалось отобразить следующий SELECT с SQLAlchemy на обоих уровнях.

SELECT count(*) AS count_1
FROM "table"

Использование уровня SQL Expression

from sqlalchemy import select, func, Integer, Table, Column, MetaData

metadata = MetaData()

table = Table("table", metadata,
              Column('primary_key', Integer),
              Column('other_column', Integer)  # just to illustrate
             )   

print select([func.count()]).select_from(table)

Использование с уровня ORM

Вы просто подклассом Query (возможно, вы все равно) и предоставляете специализированный метод count(), например этот.

from sqlalchemy import func

class BaseQuery(Query):
    def count_star(self):
        count_query = (self.statement.with_only_columns([func.count()])
                       .order_by(None))
        return self.session.execute(count_query).scalar()

Обратите внимание, что order_by(None) сбрасывает порядок запроса, что не имеет отношения к счету.

Используя этот метод, вы можете иметь count(*) в любом запросе ORM, который будет соблюдать все уже указанные условия filter и join.

Ответ 2

Запрос только для одного известного столбца:

session.query(MyTable.col1).count()

Ответ 3

Мне нужно было сделать счет очень сложного запроса со многими объединениями. Я использовал соединения в качестве фильтров, поэтому мне хотелось узнать только количество фактических объектов. count() было недостаточно, но я нашел ответ в документах здесь:

http://docs.sqlalchemy.org/en/latest/orm/tutorial.html

Код будет выглядеть примерно так (для подсчета объектов пользователя):

from sqlalchemy import func

session.query(func.count(User.id)).scalar() 

Ответ 4

Если вы используете подход SQL Expression Style, есть другой способ создать оператор count, если у вас уже есть объект таблицы.

Подготовка к получению табличного объекта. Есть и разные способы.

import sqlalchemy

database_engine = sqlalchemy.create_engine("connection string")

# Populate existing database via reflection into sqlalchemy objects
database_metadata = sqlalchemy.MetaData()
database_metadata.reflect(bind=database_engine)

table_object = database_metadata.tables.get("table_name") # This is just for illustration how to get the table_object                    

Выдача запроса на подсчет для table_object

query = table_object.count()
# This will produce something like, where id is a primary key column in "table_name" automatically selected by sqlalchemy
# 'SELECT count(table_name.id) AS tbl_row_count FROM table_name'

count_result = database_engine.scalar(query)