【问题标题】:Sql alchemy quote database bind parameter on postgrespostgres中的Sqlalchemy报价数据库绑定参数
【发布时间】:2019-10-03 22:47:58
【问题描述】:

我是 sql alchemy 的新手。

我有一个postgres本地服务器,我想用sql alchemy创建一个数据库。

我有以下代码:

connection = engine.connect()
connection.execute(
    text("CREATE DATABASE :database_name").bindparams(bindparam('database_name', quote=False)),
    database_name="test_db"
)

但不幸的是,这对数据库名称参数进行了单引号,这在 postgres 中不起作用。来自 sql alchemy 的日志:

[SQL: CREATE DATABASE %(database_name)s]
[parameters: {'database_name': 'test_db'}]
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.SyntaxError) syntax error at or near "'test_db'" LINE 1: CREATE DATABASE 'test_db`'

在postgres日志中,执行如下语句,由于单引号导致无效。一个有效的应该有双引号:

CREATE DATABASE 'test_db'

有没有办法在结果语句中不引用绑定参数?我不想自己进行参数引用和字符串创建,因为我认为这种抽象应该由 sql alchemy 处理 - 以防我更改我的底层数据库引擎,例如,这看起来是 sql alchemy 促进避免使用 sql 的机制也注射。

同样的问题也适用于其他 postgres 语句,例如使用密码创建用户,或授予现有用户权限,所有这些都需要引用 postgres 特定的。

【问题讨论】:

  • 重新考虑您的数据库设计和/或项目需求。 CREATE DATABASE 是一个强有力的声明,因为它建立了整个内部结构。虽然您的目标是针对 SQL 注入的最佳实践,但出于安全性和持久性原因,您还应该注意正确的设计,而不是在应用层构建数据库。

标签: python postgresql sqlalchemy


【解决方案1】:

您不能在 SELECTINSERTUPDATEDELETE 以外的语句中使用参数。

您必须将CREATE DATABASE 语句构造为包含数据库名称的字符串。类似的东西

from psycopg2 import sql

cursor.execute(
    sql.SQL("CREATE DATABASE {}").format(sql.Identifier('test_db'))
)

【讨论】:

  • 我得到一个“sqlalchemy.exc.ObjectNotExecutableError: Not an executable object: Composed([SQL('CREATE DATABASE '), Identifier('test_db')])”。我也在寻找可以跨其他数据库工作的东西,所以如果我更改为 Mysql 或 SqlServer,我不必更改我的导入并使用其他东西。
  • 我修复了这个例子。 cursor 应该是一个 psycopg2 游标。 CREATE DATABASE 绝对不是适用于所有 RDBMS 的语句。它甚至不在标准中。如果它有效,它在不同的 RDBMS 中意味着完全不同的东西。
  • 这不是 SQLAlchemy 解决方案,而是 DB-API pyscopg2 解决方案。此外,没有两个 RDBMS 是相同的以便于互换。而且我会避免在 Python 等应用层脚本中动态创建数据库。数据库、模式、用户等应该是计划好的、手动的、一次性的事件,而不是在代码中运行。
猜你喜欢
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多