Python中如何使用SQLAlchemy进行SQL语句拼接
array = [1,2,3,4,5] #我的是一个数组,数量未知,我想实现下面的效果,怎么拼接呀?
func.find_in_set(1, cls.types) 就是把数组里的数字一个个的填入这里面,然后有多少就组合多少个;
效果
data = MysqlDB.session.query(cls).filter(
and_(
func.find_in_set(1, cls.types),
func.find_in_set(2, cls.types),
func.find_in_set(3, cls.types),
func.find_in_set(4, cls.types),
func.find_in_set(5, cls.types)
)
).limit(limit).all()
一天了都没拼接组合出来。实在没办法了。来问一下前辈们。
其实我是想查询数据库,表结构
id----types
1----1,2,3
2----7,8,9
3----15,8,3
4----17,2,5
5----9,7,12
假设我想查询 包含 2 和 5 的
就会出现第 4 条数据。我测试了这个查询语句是可用的,并且准确的;
可是现在就是不会组合拼接。
因为我的查询给的 types 长度不一定,内容也不一定。
Python中如何使用SQLAlchemy进行SQL语句拼接
[func.find_in_set(x, cls.types) x for x in array]
把这个*list 放入 and_里?
在SQLAlchemy里,拼接SQL语句主要有两种方式:使用text()函数执行原始SQL,或者用Core表达式构建动态查询。
1. 使用text()执行原始SQL
当你有完整的SQL字符串时,可以用text()包装并执行:
from sqlalchemy import text
# 基础SQL拼接
sql = text("SELECT * FROM users WHERE name = :name")
result = conn.execute(sql, {"name": "john"})
# 动态条件拼接
conditions = []
params = {}
if filter_name:
conditions.append("name = :name")
params['name'] = filter_name
if filter_age:
conditions.append("age > :age")
params['age'] = filter_age
where_clause = " AND ".join(conditions)
sql = text(f"SELECT * FROM users WHERE {where_clause}")
result = conn.execute(sql, params)
2. 使用Core表达式构建(推荐) 这是更安全、更Pythonic的方式:
from sqlalchemy import create_engine, MetaData, Table, select
# 定义表结构
metadata = MetaData()
users = Table('users', metadata, autoload_with=engine)
# 动态构建查询
query = select(users)
if filter_name:
query = query.where(users.c.name == filter_name)
if filter_age:
query = query.where(users.c.age > filter_age)
# 执行查询
result = conn.execute(query)
3. 复杂条件拼接
from sqlalchemy import and_, or_
# AND/OR组合
conditions = []
if filter_name:
conditions.append(users.c.name.like(f'%{filter_name}%'))
if filter_age:
conditions.append(users.c.age.between(20, 30))
if conditions:
query = select(users).where(and_(*conditions))
关键点:
- 用
text()时一定要参数化查询(:param语法)防止SQL注入 - Core表达式方式会自动处理参数转义,更安全
- 两种方式可以混合使用:
text()片段嵌入表达式
建议:优先使用Core表达式构建查询。
额。不行。 = =这样是不行的。
我也是这么想的😂问题出在哪儿了?
试试 cls.types.in_(arrays)
#2 是否加了*解包?
建议抽空看看 SQL 反模式第一部分第二章: 乱穿马路
不能换个写法吗
data = MysqlDB.session.query(cls)
for i in array:
data = data.filter(func.find_in_set(i, cls.types))
data = data.limit(limit).all()
不知道这样行吗
func.find_in_set 的返回值需要是 sqlalchemy.sql.elements.BinaryExpression

