Ошибка: столбец "test" не существует
Почему не работает? Как исправить?
import psycopg2
from psycopg2 import Error
tableLit = 'gt_zavod_1_92_25'
try:
connection = psycopg2.connect(user="postgres",
password="Best4KamCH",
host="127.0.0.1",
port="5432",
database="postgres")
cursor = connection.cursor()
test = ['800']
postgres_insert_query_z1 = ("""SELECT liter FROM {table} WHERE cm = test""")
cursor.execute(postgres_insert_query_z1.format(table=tableLit))
hhz = cursor.fetchall()
print(hhz)
if connection:
online_base = 1
cursor.close()
connection.close()
print("Соединение с PostgreSQL закрыто")
except (Exception, Error) as error:
print("Ошибка при работе с PostgreSQL", error)
Выдает ошибку:
Ошибка при работе с PostgreSQL ОШИБКА: столбец "test" не существует
LINE 1: SELECT liter FROM gt_zavod_1_92_25 WHERE cm = test[0]
^
Ответы (2 шт):
Когда Вы делаете передаёте SQL-серверу строку postgres_insert_query_z1:
cursor.execute(postgres_insert_query_z1.format(table=tableLit))
то говорите, что имя таблицы надо взять из переменной table=tableLit и поэтому на сервер приходит строка, начинающаяся с
SELECT liter FROM gt_zavod_1_92_25
Но с окнчанием этой строки - проблема. Там написано WHERE cm = test, но SQL сервер ничего не знает о том. что такое test. Поэтому, он пытается найти это имя в списке колонок своих таблиц. Такого имени нет. Вот он Вам и говорит:
PostgreSQL ОШИБКА: столбец "test" не существует
Решение очевидно. Надо в исходной строке заменить "test" на "{test}", а при отправке этой строки на сервер указать конкретное значение этой переменной:
value=1234
.format(table=tableLit,test=value)
Наиболее правильный подход в данном случае - это воспользоваться форматированием для подстановки имени таблицы и параметризированным запросом для подстановки значений литералов:
qry_template = """SELECT liter FROM {table} WHERE cm = %s"""
...
cursor.execute(qry_template.format(table=tableLit), [test[0]])
Данный подход имеет несколько преимуществ:
- обезопасит вас от
SQL Injections - DB драйвер сам позаботится об экранировании и форматировании. Например если вы передаете переменную типа
datetimeв качестве параметра, то вам не придется специально форматировать дату/время. - в большинстве БД параметризированные запросы будут выполняться быстрее в цикле, т.к. такой запрос будет проверен на правильность синтаксиса, на права доступа к DB объектам и распарсен только один раз и сохранен в памяти БД.
NOTE: параметризированные запросы не позволяют указывать имена SQL объектов (например имена таблиц, столбцов, индексов, etc.) в качестве параметров.