I'd like to know if it's possible to generate a SELECT COUNT(*) FROM TABLE
statement in SQLAlchemy without explicitly asking for it with execute()
. If I use:
session.query(table).count()
then it generates something like:
SELECT count(*) AS count_1 FROM (SELECT table.col1 as col1, table.col2 as col2, ... from table)
which is significantly slower in MySQL with InnoDB. I am looking for a solution that doesn't require the table to have a known primary key, as suggested in Get the number of rows in table using SQLAlchemy.
To counts all of the rows in a table, whether they contain NULL values or not, use COUNT(*). That form of the COUNT() function basically returns the number of rows in a result set returned by a SELECT statement.
The select() method of table object enables us to construct SELECT expression. The resultant variable is an equivalent of cursor in DBAPI. We can now fetch records using fetchone() method. Here, we have to note that select object can also be obtained by select() function in sqlalchemy.
Use the COUNT aggregate function to count the number of rows in a table. This function takes the name of the column as its argument (e.g., id ) and returns the number of rows for this particular column in the table (e.g., 5).
I managed to render the following SELECT with SQLAlchemy on both layers.
SELECT count(*) AS count_1 FROM "table"
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)
You just subclass Query
(you have probably anyway) and provide a specialized count()
method, like this one.
from sqlalchemy.sql.expression 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()
Please note that order_by(None)
resets the ordering of the query, which is irrelevant to the counting.
Using this method you can have a count(*)
on any ORM Query, that will honor all the filter
andjoin
conditions already specified.
Query for just a single known column:
session.query(MyTable.col1).count()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With