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

如何借助SQLAlchemy跨多数据库可靠识别只读SQL语句?

判断SQL语句是否需要非只读权限的最佳实现方式

方案1:通过SQLAlchemy解析语句类型

SQLAlchemy的text()对象可以解析SQL语句并识别其操作类型,直接通过内置属性判断是否属于只读操作:

from sqlalchemy import text

raw_query = "SELECT * FROM table"
parsed_stmt = text(raw_query)

# 仅SELECT类语句属于只读
is_read_only = parsed_stmt.is_select or parsed_stmt.is_textual_select

# 检查是否为修改类语句
if parsed_stmt.is_insert or parsed_stmt.is_update or parsed_stmt.is_delete or parsed_stmt.is_ddl:
    print("该语句需要非只读权限")
else:
    print("该语句仅需只读权限")

注意:对于包含多命令的复杂SQL脚本,需要遍历所有子语句逐一判断,避免遗漏修改操作。

方案2:用只读连接测试执行(最可靠)

直接借助数据库自身的权限校验机制,用只读权限的连接尝试执行语句(在事务中执行后回滚),如果触发权限错误则说明需要非只读权限:

from sqlalchemy import text
from sqlalchemy.exc import ProgrammingError, OperationalError

def requires_write_permission(raw_query, read_only_engine):
    try:
        with read_only_engine.connect() as conn:
            trans = conn.begin()
            conn.execute(text(raw_query))
            trans.rollback()  # 回滚避免意外修改
        return False
    except (ProgrammingError, OperationalError) as e:
        err_msg = str(e).lower()
        if "permission denied" in err_msg or "read-only" in err_msg:
            return True
        # 语法错误等其他异常不属于权限问题,直接抛出
        raise

这种方式完全适配所有数据库类型,不会因为SQL解析漏洞误判,是最可靠的方案。

方案3:第三方SQL解析库(轻量场景)

用sqlparse库直接分析SQL字符串中的关键字,适合不需要数据库连接的轻量场景:

import sqlparse
from sqlparse.tokens import DML, DDL

def is_write_sql(raw_query):
    parsed = sqlparse.parse(raw_query)[0]
    for token in parsed.tokens:
        if token.ttype == DML and token.value.upper() in ('INSERT', 'UPDATE', 'DELETE', 'MERGE'):
            return True
        if token.ttype == DDL and token.value.upper() in ('CREATE', 'ALTER', 'DROP', 'TRUNCATE'):
            return True
    return False

注意:需要自行处理注释、大小写、多语句等边界情况,复杂SQL可能出现误判。

选择建议

  • 优先选方案2,可靠性最高;
  • 若不想连接数据库,选方案1,SQLAlchemy的解析已适配多数主流数据库;
  • 简单场景或离线分析可选方案3,需额外完善解析逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:32:49