Psycopg2 имеет двойные кавычки вокруг заполнителя

Интерфейс командной строки Postgres:

Используя одинарные кавычки вокруг имени пользователя, я получаю сообщение об ошибке:

some_db=> CREATE USER 'foobar' WITH PASSWORD 'pass';
                      ^      ^
ERROR:  syntax error at or near "'foobar'"
LINE 1: CREATE USER 'foobar' WITH PASSWORD 'pass';

Но двойные кавычки хороши:

some_db=> CREATE USER "foobar" WITH PASSWORD 'pass';
                      ^      ^
CREATE ROLE

Код Python:

При выполнении этого фрагмента кода:

db_connection.cursor().execute(
  "CREATE USER %s WITH PASSWORD %s",
  (username, password,)
)

Я также получаю сообщение об ошибке:

Error creating User: syntax error at or near "'foobar'"
LINE 1: CREATE USER 'foobar' WITH PASSWORD '9f...

Это ожидаемо, поскольку одинарные кавычки добавляются автоматически при использовании параметров запроса.

Вопрос: есть ли способ настроить psycopg2 на использование двойных кавычек или мне нужно встроить переменную username непосредственно в запрос? Или может быть есть другое решение? Если второй случай — это путь, мне тоже нужно избежать его. Что вы думаете?

🤔 А знаете ли вы, что...
PostgreSQL поддерживает репликацию данных для обеспечения отказоустойчивости и масштабируемости.


50
1

Ответ:

Решено

Из модуля psycopg2sql:

import psycopg2
from psycopg2 import sql
con = psycopg2.connect("dbname=test user=postgres port=5432")
cur = con.cursor()
cur.execute(sql.SQL("create user {} with password %s").format(sql.Identifier('test_usr')), ['test'])
con.commit()
cur.execute("select usename from pg_user where usename = 'test_usr'")
cur.fetchone()
('test_usr',)

Это безопасный способ создания динамического SQL.

ОБНОВЛЯТЬ Уточнение происходящего:

user_sql = sql.SQL("create user {} with password %s").format(sql.Identifier('test_usr'))

print(user_sql.as_string(con))
create user "test_usr" with password %s

Модуль sql создает строку SQL, в которой части компонентов правильно экранируются, чтобы обеспечить их безопасность. Предостережение: при использовании sql.SQL можно совершать небезопасные действия, если неправильно отформатировать биты переменных:

класс psycopg2.sql.SQL(строка)

Composable, представляющий фрагмент оператора SQL.

SQL предоставляет методы join() и format(), полезные для создания шаблона для объединения переменных частей запроса (например, имен полей или таблиц).

Строка не подвергается никакой форме экранирования, поэтому она не подходит для представления идентификаторов или значений переменных: ее следует использовать только для передачи константных строк, представляющих шаблоны или фрагменты операторов SQL; используйте другие объекты, такие как Identifier или Literal, для представления переменных частей.

Обязательно прочитайте этот sql, чтобы убедиться, что вы поступаете правильно.