You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flask-SQLAlchemy中以字符串形式传入数据库模型名称?

安全实现用字符串模型名执行Flask-SQLAlchemy查询的方法

这个问题我之前做项目时也碰到过,直接用字符串调用query肯定会报错,毕竟字符串本身只是文本,根本没有query属性嘛。下面给你两个安全可靠的实现思路,完全避开危险的eval操作:

方法一:利用Flask-SQLAlchemy内置的模型字典

Flask-SQLAlchemy的SQLAlchemy实例自带一个models字典,里面自动存储了所有你定义的模型类,键就是模型的类名(字符串形式)。你可以直接通过这个字典获取对应的模型类:

from flask import abort
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

# 假设你的User模型已经通过db.Model定义完成
row_id = 1
database_name = "User"

# 获取目标模型类
target_model = db.models.get(database_name)

# 先检查模型是否存在,避免后续报错
if not target_model:
    abort(404, description=f"Model {database_name} does not exist")

# 正常执行查询
row = target_model.query.filter_by(id=row_id).first_or_404()

这种方法是官方推荐的,因为db.models只包含你已经注册的合法模型,不会引入未知代码,安全性拉满。

方法二:手动维护模型映射字典

如果想更可控(比如只允许特定模型被字符串调用),可以自己定义一个映射字典,把允许的模型类和对应的字符串名称关联起来:

from flask import abort
from your_app.models import User, Post, Comment  # 导入你项目中的模型

# 手动定义允许通过字符串调用的模型
ALLOWED_MODELS = {
    "User": User,
    "Post": Post,
    "Comment": Comment
}

row_id = 1
database_name = "User"

target_model = ALLOWED_MODELS.get(database_name)
if not target_model:
    abort(404, description=f"Model {database_name} is not accessible")

row = target_model.query.filter_by(id=row_id).first_or_404()

这种方式的优势在于你可以严格控制哪些模型能被字符串调用,进一步降低风险,适合有严格权限控制的生产环境场景。

为什么绝对不能用eval?

很多人可能会想到用eval(database_name)直接把字符串转成类,但这种做法极度危险——如果database_name是用户输入的恶意字符串(比如"os.system('rm -rf /')"),会直接执行任意代码,造成毁灭性的安全漏洞。上面两种方法都完全避开了这种风险,是生产环境的首选。

内容的提问来源于stack exchange,提问作者cccnrc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 12:52:35