如何使用Tortoise ORM执行原生SQL?
Tortoise ORM 执行原生SQL的操作方法
Tortoise ORM 本身提供了原生SQL执行的底层接口,不需要额外引入第三方类,直接通过数据库连接实例调用对应方法即可,以下是不同场景的用法:
1. 执行查询类SQL(返回结果集)
适用于SELECT类查询,需要获取返回数据的场景,调用execute_query方法:
from tortoise import Tortoise # 构造SQL语句,使用对应数据库的参数占位符(SQLite/MySQL用?或%s,PostgreSQL用$1、$2) sql = "SELECT id, username, age FROM users WHERE age > ? AND is_active = ?" # 按顺序传入预编译参数,避免SQL注入 params = [18, True] # 获取对应数据库连接(默认别名为default,和配置文件中的数据库别名保持一致) conn = Tortoise.get_connection("default") # 执行查询,返回值为(受影响行数, 结果列表),结果列表的每个元素是字段名映射值的字典 affected_count, rows = await conn.execute_query(sql, params) # 遍历结果示例 for row in rows: print(f"用户ID:{row['id']},用户名:{row['username']}")
2. 执行增删改类SQL(仅需获取影响行数)
适用于INSERT、UPDATE、DELETE类操作,仅需要判断执行是否成功或获取受影响行数的场景,同样可以用execute_query方法:
sql = "UPDATE users SET level = level + 1 WHERE score > ?" params = [1000] conn = Tortoise.get_connection("default") affected_rows, _ = await conn.execute_query(sql, params) print(f"共有{affected_rows}个用户等级提升")
3. 批量执行同结构SQL
适用于批量插入、批量更新等重复执行同结构SQL的场景,调用execute_many方法提升性能:
sql = "INSERT INTO goods (name, price, stock) VALUES (?, ?, ?)" # 传入多组参数 params_list = [ ("商品A", 29.9, 100), ("商品B", 49.9, 200), ("商品C", 9.9, 500) ] conn = Tortoise.get_connection("default") await conn.execute_many(sql, params_list)
4. 执行多语句SQL/DDL语句
适用于执行建表、改表等DDL语句,或者同时执行多条SQL的场景,调用execute_script方法:
sql = """ DROP TABLE IF EXISTS temp_data; CREATE TABLE temp_data ( id INT PRIMARY KEY AUTO_INCREMENT, data VARCHAR(255) NOT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; """ conn = Tortoise.get_connection("default") await conn.execute_script(sql)
注意事项
- 所有原生SQL执行方法都是异步方法,必须加
await调用,且只能在异步上下文中执行 - 禁止直接拼接字符串构造SQL,必须通过预编译参数传递动态值,避免SQL注入风险
- 如果在模型类的内部方法中调用,可以直接通过
模型类._meta.db获取该模型对应的数据库连接,无需手动填写连接别名
内容的提问来源于stack exchange,提问作者sx Luo
相关产品推荐
相关产品推荐

