Форматирование строки Psycopg2 с именами переменных для создания типа

При передаче имени типа переменной для создания в postgres с использованием psycopg2 с использованием его параметра форматирования возникала ошибка из-за неправильного форматирования строки для имени объектов. Нельзя ли передавать имена с помощью %s в параметрах запроса?

Код, который я написал, который решает мои проблемы, приведен ниже (просто ищу лучший способ решить эту проблему)

cursor.execute("CREATE TYPE {0} AS ENUM %s".format(name), (tuple(set([e.upper() for e in elements])),))

person Jjensen.mike    schedule 07.10.2012    source источник


Ответы (3)


(2) совершенно не связан с PostgreSQL, возможно, отредактируйте его из этого вопроса и опубликуйте в новом вопросе? Я отвечу (1).

Как вы уже догадались, вы не можете передавать такие вещи, как имена таблиц, в качестве параметров запроса.

Они отправляются как параметры привязки на уровне протокола, и (что очень важно) запрос должен анализироваться как действительный SQL с ними в качестве заполнителей. Это как если бы вы запускали SQL-уровень PREPARE, а затем разделяли EXECUTE. Вы должны отформатировать их в строку SQL перед ее подготовкой, используя соответствующие кавычки идентификатора.

Двойные кавычки идентификаторов, которые вы подставляете, и остерегайтесь возможных двойных кавычек в передаваемой строке, которые могут преждевременно закончить вашу последовательность в кавычках. Они должны быть удвоены. Например, для имени таблицы some"table вы должны использовать:

 'SELECT * FROM "{0}"'.format('some""table');

SQL-инъекция представляет собой очень серьезный риск; вы должны правильно цитировать точно. В идеале найдите клиентский эквивалент функции PostgreSQL quote_ident SQL.

Обратите внимание, что идентификаторы в двойных кавычках чувствительны к регистру. Убедитесь, что вы создаете их с одним и тем же регистром в БД, всегда используя их в двойных кавычках, не смешивайте идентификаторы в кавычках и без кавычек.

person Craig Ringer    schedule 08.10.2012

На самом деле вы никогда не должны форматировать свои запросы в формате python, но пусть это сделает psycopg2. Вот как это сделать: http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries, то есть:

cur.execute("INSERT INTO numbers VALUES (%s)", (42,))

Начиная с версии 2.7, некоторые расширенные возможности форматирования доступны через модуль psycopg2.sql: http://initd.org/psycopg/docs/sql.html

person Rmatt    schedule 09.01.2017

Я также столкнулся с этой проблемой и написал короткий сообщение в блоге, в котором рассказывается о подключении к удаленная база данных с использованием форматирования строк, но эта проблема и мое решение применимы к любой ситуации, когда вам нужно передать переменные в команды SQL.

Вот как я работал над этой проблемой:

import psycopg2 as db
import sys

my_host = 'ec2-190-111-829-829.compute-1.amazonaws.com'
my_dbname = 'myDBNameGoesHere'
my_user = 'myUsernameGoesHere'
my_password = 'myPasswordGoesHere'
remote_connection_str = 'host={0} dbname={1} user={2} password={3}'.format(my_host, my_dbname, my_user, my_password)

if __name__ == '__main__':
     try:
          remote_connection = db.connect(remote_connection_str)
          cursor = remote_connection.cursor()
          cursor.execute('SELECT version()')
          version = cursor.fetchone()
          print "\n"
          print "Successful connection to database."
          print "Database information:\n", version
          print "\n"

     except db.DatabaseError, e:
          print 'Error %s' % e
          sys.exit(1)

     finally:
          if remote_connection:
          remote_connection.close()
person Joe Fusaro    schedule 07.10.2013