Выполнить выбор SQL в операторе, используя pygresql (модуль pg) - PullRequest
2 голосов
/ 06 марта 2019

Я работаю над сценарием Python для подключения к базам данных postgress с помощью модуля pygresql.Ниже приведен код

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

select sum(column1) from table_name where column2 in %s,(tuple,).

Но я продолжаю получать сообщение об ошибке "ОШИБКА: синтаксическая ошибка в или около"% "".

import pg
tup_ids=('a','b','c')
def connection(cs):   
  """
      :param cs: cs is connection string
      :return:
       """
      conn=pg.connect(cs)
      return conn
conn1 = connection(conn_string)
conn1.query('select sum(column1) from table_name where column2 in %s',(tup_ids,).

Я могу выполнить запрос с помощью модуля psycopg2,Я не могу передать параметр кортежа для модуля pg.Я был pgresql документации.Я не уверен, где я делаю неправильно.

К вашему сведению: мне нужно использовать только модуль pygresql.Пожалуйста, помогите.

Ответы [ 2 ]

3 голосов
/ 07 марта 2019

PyGreSQL "classic" (модуль pg) поддерживает собственные параметры PostgreSQL в своем методе query с меткой $1, $2, ... К сожалению, они принимают только отдельные значения, поэтомусначала вы должны создать список параметров с таким количеством значений, как ваш кортеж.Однако это очень просто:

con = pg.connect(cs)
p_list = ','.join('$%d' % n for n in range(1, len(tup_ids) + 1))
q = con.query('select sum(column1) from table_name where column2 in (%s)' % p_list, tup_ids)
print(q.getresult())

В качестве альтернативы вы можете использовать метод query_formatted, доступный в классе-оболочке DB PyGreSQL classic (рекомендуется использовать этоВо всяком случае, обертка вместо необработанных соединений, потому что она добавляет много удобных методов).Этот метод использует форматирование Python, поэтому его необходимо использовать следующим образом:

db = pg.DB(cs)
p_list = ','.join(['%s'] * len(tup_ids))
q = db.query_formatted(
    'select sum(column1) from table_name where column2 in (%s)' % p_list, tup_ids)
print(q.getresult())

Используя ANY вместо IN в своем выражении SQL, вы можете избежать создания списка параметров и передавать значенияв виде одного списка:

db = pg.DB(cs)
q = db.query_formatted(
    'select sum(column1) from table_name where column2 = any(%s)', [list(tup_ids)])
print(q.getresult())

Модуль PyGreSQL DB API 2 (pgdb) также использует форматирование Python и работает аналогично:

con = pgdb.connect(cs)
cur = con.cursor()
cur.execute('select sum(column1) from table_name where column2 = any(%s)', [list(tup_ids)])
print(cur.fetchone())

Обратите внимание, что мы всегда передавали параметры отдельно.Не пытайтесь * передать запрос со значениями в формате Python, так как это подвержено ошибкам и является проблемой безопасности («внедрение SQL»), даже если это выглядит проще:

con = pg.connect(cs)  # do NOT do this:
q = con.query('select sum(column1) from table_name where column2 in %s' % (tup_ids,))
1 голос
/ 06 марта 2019

Пожалуйста, используйте "?" символ в вашей команде выбора SQL

В вашем случае вы должны изменить на:

conn.query ('выберите сумму (column1) из table_name, где column2 в ?», (Tup_ids))

Тогда он должен выполнить с успехом

...