如何使用 sqlalchemy 创建 postgres 用户

Fra*_*uga 9 python postgresql sqlalchemy

我需要允许通过在后端使用 python 和 sqlalchemy 的 Web 应用程序创建数据库用户/角色。

为此,我使用类似的东西:

sql = 'CREATE USER :username WITH PASSWORD :passwd'
sql_data = {
    'username': 'the_user_name',
    'passwd': 'the_password',
}
request.db.execute(sql, sql_data)
Run Code Online (Sandbox Code Playgroud)

但是这个查询创建的 SQL 是:

CREATE USER 'the_user_name' WITH PASSWORD 'the_password'
Run Code Online (Sandbox Code Playgroud)

我需要的是:

CREATE USER "the_user_name" WITH PASSWORD 'the_password'
Run Code Online (Sandbox Code Playgroud)

用户名正确转义。sqlalchemy 有没有办法处理这个问题,还是我应该手动创建字符串?如果是这样,我该如何转义用户输入名称?

Ale*_*x W 2

使用quoted_name

表示与引用首选项相结合的 SQL 标识符。

Quoted_name 是 Python unicode/str 子类,它表示特定的标识符名称以及引号标志。当设置为 True 或 False 时,此引用标志会覆盖此标识符的自动引用行为,以便无条件引用或不引用名称。如果保留默认值 None,则根据对令牌本身的检查,将引用行为应用于每个后端的标识符。

以下是我如何让它工作的:

from sqlalchemy.sql import text, quoted_name

DATABASE_USER = "your_user_here"
DATABASE_USER_PASSWORD = "your_password"

create_user_sql = text(f"CREATE USER {quoted_name(DATABASE_USER, False)} WITH PASSWORD :database_password")\
    .bindparams(                                     # You can remove this line if you don't want to test
        database_password=DATABASE_USER_PASSWORD.    # You can remove this line if you don't want to test
    )\                                               # You can remove this line if you don't want to test
    .compile(compile_kwargs={"literal_binds": True}) # You can remove this line if you don't want to test
print(str(create_user_sql))                          # You can remove this line if you don't want to test
Run Code Online (Sandbox Code Playgroud)

执行结果如下:

CREATE USER your_user_here WITH PASSWORD 'your_password'
Run Code Online (Sandbox Code Playgroud)

您可以删除.bindparams()and.compile()并仅将参数传递给看起来更干净的参数connection.execute(create_user_sql, database_password=DATABASE_USER_PASSWORD),上面的代码只是概念证明。