#python #postgresql #null #psycopg2 #nonetype
Вопрос:
Существует ли хорошая практика ввода NULL
значений ключей в базу данных PostgreSQL, когда переменная находится None
в Python?
Выполнение этого запроса:
mycursor.execute('INSERT INTO products (user_id, city_id, product_id, quantity, price) VALUES (%i, %i, %i, %i, %f)' %(user_id, city_id, product_id, quantity, price))
приводит к TypeError
исключению, когда user_id
есть None
.
Как можно NULL
вставить a в базу данных , если значение равно None
, используя psycopg2
драйвер?
Комментарии:
1. Какой адаптер DB-API вы используете?
2. под адаптером DB-API я полагаю, вы имеете в виду интерфейс бд psycopg2. Если нет, можете ли вы быть более конкретным?
Ответ №1:
Чтобы вставить нулевые значения в базу данных, у вас есть два варианта:
- опустите это поле в инструкции INSERT или
- использовать
None
Также: Для защиты от SQL-инъекции вам не следует использовать обычную интерполяцию строк для ваших запросов.
Вы должны передать два (2) аргумента execute()
, например:
mycursor.execute("""INSERT INTO products
(city_id, product_id, quantity, price)
VALUES (%s, %s, %s, %s)""",
(city_id, product_id, quantity, price))
Альтернатива № 2:
user_id = None
mycursor.execute("""INSERT INTO products
(user_id, city_id, product_id, quantity, price)
VALUES (%s, %s, %s, %s, %s)""",
(user_id, city_id, product_id, quantity, price))
Комментарии:
1. Спасибо. Можете ли вы указать мне где-нибудь, чтобы я мог прочитать, почему интерполяция строк в python может привести к sql-инъекции. Это очень интересно, и я об этом не подумал.
2. Пожалуйста. Это хорошо описывает, что такое атаки с использованием SQL-инъекций: en.wikipedia.org/wiki/SQL_injection Как это связано с интерполяцией строк?: Допустим, вы получаете ненадежный ввод в свою программу. Этот ввод может содержать, например,
DROP TABLE
команду.3. Я использую None для значения столбца, но получаю ошибку: Ошибка программирования: столбец «none» не существует СТРОКА 1: …01.00-ng20′, report_date=’2016-03-30′, ec_enabled=Нет, ec_s… Вот исходный запрос, который не удался: ОБНОВИТЕ kw_daily_data_mart, УСТАНОВИТЕ имя хоста=’ctrlkey.com’, users_licensed=7, licensed_users=10, sw_version=’kw2016.01.00-ng20′, дата отчета=’2016-03-30′, ec_enabled=Нет, ec_server_count=1, config_max_file_version=10, av_enabled=True, location_count=1, sso_enabled=False, ГДЕ идентификатор пользователя=127892, идентификатор установки=3585 И имя хоста=’ctrlkey.com» ВОЗВРАЩАЮ удостоверение личности
4. Я тоже не использую ни одного, и я получаю ту же ошибку, что и @Varun. Тот же пакет python psycopg2, v2.6.2. Posgresql v9.6
5. Решение также работает с запросом на обновление. Спасибо, что поделились!
Ответ №2:
В текущем psycopg вместо » Нет «используйте переменную, равную «NULL».
variable = 'NULL'
insert_query = """insert into my_table values(date'{}',{},{})"""
format_query = insert_query.format('9999-12-31', variable, variable)
curr.execute(format_query)
conn.commit()
>> insert into my_table values(date'9999-12-31',NULL,NULL)
Комментарии:
1. это работает для psycopg2 2.8.4, решение с вставкой None заканчивается значением «None» в бд, по крайней мере, для postgres
2. Если вставляемое поле является текстовым полем, используя «NULL», просто вставьте эти четыре символа. Приведенный выше ответ (использование
None
) является правильным.
Ответ №3:
Вот мое решение:
text = 'INSERT INTO products (user_id, city_id, product_id, quantity, price) VALUES (%i, %i, %i, %i, %f)' %(user_id, city_id, product_id, quantity, price))
text = text.replace("nan", "null")
mycursor.execute(text)
Ответ №4:
Более простой подход, который также практичен при большом количестве столбцов:
Пусть row
будет список вставляемых значений, которые могут содержать None
. Чтобы вставить его в PostgreSQL, мы делаем следующее
values = ','.join(["'" str(i) "'" if i else 'NULL' for i in row])
cursor.execute('insert into myTable VALUES ({});'.format(values))
conn.commit()
Комментарии:
1. Возможно, это не по теме, но я мог бы предложить не вставлять в таблицу без указания имен столбцов.