SQLAlchemy 中的 func 函数使用指南

func 是 SQLAlchemy 中用于调用 SQL 函数的关键工具,它允许你在查询中使用数据库的各种内置函数。

基本介绍

funcsqlalchemy.sql.functions 模块中的一个特殊对象,它作为 SQL 函数的命名空间使用。当你访问 func 的属性时,SQLAlchemy 会创建一个对应的 SQL 函数调用。

常用函数示例

1. 聚合函数

python 复制代码
from sqlalchemy import func
from models import User, Session

session = Session()

# 计数
total_users = session.query(func.count(User.id)).scalar()

# 求和
total_salary = session.query(func.sum(User.salary)).filter(User.department == 'IT').scalar()

# 平均值
avg_age = session.query(func.avg(User.age)).scalar()

# 最大值/最小值
max_salary = session.query(func.max(User.salary)).scalar()
min_age = session.query(func.min(User.age)).scalar()

2. 字符串函数

python 复制代码
# 字符串连接
session.query(func.concat(User.first_name, ' ', User.last_name).label('full_name')).all()

# 小写转换
session.query(func.lower(User.username)).all()

# 子字符串
session.query(func.substr(User.email, 1, 5)).all()

# 字符串长度
session.query(func.length(User.address)).all()

3. 日期时间函数

python 复制代码
from datetime import datetime

# 当前日期时间
session.query(func.now()).scalar()

# 提取年份
session.query(func.extract('year', User.created_at)).all()

# 日期格式化
session.query(func.strftime('%Y-%m-%d', User.birth_date)).all()

# 日期差
session.query(func.datediff('day', User.start_date, User.end_date)).all()

4. 数学函数

python 复制代码
# 随机数
session.query(User).order_by(func.random()).first()  # PostgreSQL/SQLite
session.query(User).order_by(func.rand()).first()    # MySQL

# 绝对值
session.query(func.abs(User.balance)).all()

# 四舍五入
session.query(func.round(User.score, 2)).all()

# 平方根
session.query(func.sqrt(User.area)).all()

5. 条件表达式

python 复制代码
# CASE WHEN 表达式
session.query(
    func.case(
        [(User.age < 18, 'minor'),
         (User.age >= 18, 'adult')],
        else_='unknown'
    ).label('age_group')
).all()

# COALESCE (返回第一个非NULL值)
session.query(func.coalesce(User.nickname, User.first_name)).all()

# NULLIF (两值相等返回NULL)
session.query(func.nullif(User.salary, 0)).all()

高级用法

1. 函数组合

python 复制代码
# 计算每个用户邮箱域名的长度
session.query(
    func.length(
        func.substr(
            User.email,
            func.instr(User.email, '@') + 1
        )
    )
).all()

2. 自定义函数标签

python 复制代码
# 为函数结果指定列名
session.query(
    func.upper(User.last_name).label('last_name_upper'),
    func.lower(User.first_name).label('first_name_lower')
).all()

3. 分组中使用函数

python 复制代码
# 按年份统计用户数量
session.query(
    func.extract('year', User.created_at).label('year'),
    func.count(User.id).label('user_count')
).group_by('year').all()

4. 窗口函数

python 复制代码
from sqlalchemy import over

# 计算每个部门的薪资排名
session.query(
    User.name,
    User.salary,
    func.rank().over(
        order_by=User.salary.desc(),
        partition_by=User.department
    ).label('rank')
).all()

数据库特定函数

SQLAlchemy 可以透明地处理不同数据库的函数差异:

python 复制代码
# 处理不同数据库的日期差异计算
if dialect.name == 'postgresql':
    age_expr = func.age(User.end_date, User.start_date)
elif dialect.name == 'mysql':
    age_expr = func.timestampdiff('day', User.start_date, User.end_date)
else:
    age_expr = func.julianday(User.end_date) - func.julianday(User.start_date)

自定义函数

你还可以注册和使用自定义SQL函数:

python 复制代码
from sqlalchemy import create_engine
from sqlalchemy.sql.expression import FunctionElement
from sqlalchemy.ext.compiler import compiles

# 定义自定义函数类
class my_random(FunctionElement):
    type = Numeric()
    name = 'my_random'

# 定义编译规则
@compiles(my_random, 'postgresql')
def compile_my_random_postgresql(element, compiler, **kw):
    return "my_random()"  # 调用PostgreSQL中的自定义函数

# 使用自定义函数
session.query(User).order_by(my_random()).limit(5).all()

注意事项

  1. func 生成的是 SQL 函数表达式,不是 Python 函数调用
  2. 不同数据库支持的函数可能不同,SQLAlchemy 会尽量处理这些差异
  3. 复杂的函数组合可能会影响查询性能
  4. 在可能的情况下,考虑使用 SQLAlchemy 的核心表达式而不是原始 SQL 函数

通过 func,可以充分利用数据库的强大功能,同时保持代码的数据库无关性。

相关推荐
rockmelodies3 分钟前
RSA 解密逻辑
开发语言·python
Tobiichiorigami.1 小时前
Python训练Day30
python
Dxy12393102162 小时前
python创建一个excel文件
开发语言·python·excel
涡能增压发动积4 小时前
Browser-Use Agent使用初体验
人工智能·后端·python
JustNow_Man5 小时前
【LLM】 BaseModel的作用
数据库·人工智能·python·uv
hans汉斯5 小时前
【建模与仿真】二阶邻居节点信息驱动的节点重要性排序算法
人工智能·python·算法·分类·数据挖掘·排序算法·xca
青衫客366 小时前
Python中的sys.path与PYTHONPATH全解析:模块导入路径的底层机制与最佳实践
python
御水流红叶6 小时前
安卓加固脱壳
android·开发语言·python
AI Echoes6 小时前
ChatGPT、Playground手动模拟Agent摘要缓冲混合记忆功能
人工智能·python·langchain