Je voudrais savoir s'il est possible de générer une instruction SELECT COUNT(*) FROM TABLE
dans SQLAlchemy sans la demander explicitement avec execute()
. Si j'utilise:
session.query(table).count()
alors il génère quelque chose comme:
SELECT count(*) AS count_1 FROM
(SELECT table.col1 as col1, table.col2 as col2, ... from table)
ce qui est beaucoup plus lent dans MySQL avec InnoDB. Je recherche une solution qui ne nécessite pas que la table ait une clé primaire connue, comme suggéré dans Obtenez le nombre de lignes dans la table en utilisant SQLAlchemy .
J'ai réussi à rendre le SELECT suivant avec SQLAlchemy sur les deux couches.
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)
Vous venez de sous-classe Query
(vous avez probablement de toute façon) et fournissez une méthode spécialisée count()
, comme celle-ci.
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()
Veuillez noter que order_by(None)
réinitialise l'ordre de la requête, ce qui n'est pas pertinent pour le comptage.
En utilisant cette méthode, vous pouvez avoir une count(*)
sur n'importe quelle requête ORM, qui honorera toutes les conditions filter
et join
déjà spécifiées.
Recherchez une seule colonne connue:
session.query(MyTable.col1).count()
J'avais besoin de compter une requête très complexe avec de nombreuses jointures. J'utilisais les jointures comme filtres, donc je voulais seulement connaître le nombre d'objets réels. count () était insuffisant, mais j'ai trouvé la réponse dans les documents ici:
http://docs.sqlalchemy.org/en/latest/orm/tutorial.html
Le code ressemblerait à ceci (pour compter les objets utilisateur):
from sqlalchemy import func
session.query(func.count(User.id)).scalar()
Si vous utilisez l'approche SQL Expression Style, il existe une autre façon de construire l'instruction count si vous avez déjà votre objet table.
Préparations pour obtenir l'objet table. Il existe également différentes manières.
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
Emission de la requête de comptage sur le 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)