在 SQLAlchemy 上编写一些聚合代码时发现了这个问题。
引用docs:
可以为 func 指定任何名称。如果 SQLAlchemy 不知道函数名称,它将完全按原样呈现。对于 SQLAlchemy 知道的常见 SQL 函数,该名称可能被解释为一个通用函数,该函数将被适当地编译到目标数据库。
基本上 func 会生成一个匹配属性“func”的函数。如果它不是 SQLAlchemy 知道的常用函数(如 func.count)。
为了保持任何 ORM 附带的 RDBMS 抽象的优势,我始终建议使用 ANSI functions 将代码与 DB 引擎分离。
对于一个工作示例,您可以添加一个连接字符串并执行以下代码:
from sqlalchemy.orm import sessionmaker
from sqlalchemy import func, create_engine, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.types import DateTime, Integer, String
# Add your connection string
engine = create_engine('My Connection String')
Base = declarative_base(engine)
Session = sessionmaker(bind=engine)
db_session = Session()
# Make sure to have a table foo in the db with foo_id, bar, baz columns
class Foo(Base):
__tablename__ = 'foo'
__table_args__ = { 'autoload' : True }
query = db_session.query(
func.count(Foo.bar).label('count_agg'),
func.avg(Foo.foo_id).label('avg_agg'),
func.stddev(Foo.foo_id).label('stddev_agg'),
func.stddev_samp(Foo.foo_id).label('stddev_samp_agg')
)
print(query.statement.compile())
会生成如下SQL
SELECT count(foo.bar) AS count_agg,
avg(foo.foo_id) AS avg_agg,
stddev(foo.foo_id) AS stddev_agg,
stddev_samp(foo.foo_id) AS stddev_samp_agg
FROM foo