Я постоянно получал эту ошибку при попытке вставить в массив типа INET.
psycopg2.DataError: invalid input syntax for type inet: "Inet('8.8.8.8')"
Также для некоторых вариантов я пробовал:
TypeError: not all arguments converted during string formatting
Таблица испытаний:
cursor.execute( "CREATE TABLE test( ip_list inet[] );" )
Некоторые варианты, которые я пытался заставить работать:
cursor.execute( "INSERT INTO test( ip_list ) VALUES ( %s );", ( str( { "8.8.8.8" } ) ) )
cursor.execute( "INSERT INTO test( ip_list ) VALUES ( %s );", ( str( { psycopg2.extras.Inet( "8.8.8.8" ) } ) ) )
cursor.execute( "INSERT INTO test( ip_list ) VALUES ( %s );", ( psycopg2.extras.Inet( [ "8.8.8.8", "8.8.4.4" ] ) ) )
Команда psycopg2.extras.Inet( [ "8.8.8.8", "8.8.4.4" ] ) генерирует правильный объект Inet Inet(['8.8.8.8', '8.8.4.4']).
Однако при попытке вставить это с помощью
cursor.execute( "INSERT INTO test( ip_list ) VALUES ( %s );", ( psycopg2.extras.Inet( [ "8.8.8.8", "8.8.4.4" ] ) ) )
Это дает мне ошибку: TypeError: 'Inet' object does not support indexing
Когда я попытался преобразовать его в строку перед вставкой через:
ursor.execute( "INSERT INTO test( ip_list ) VALUES ( %s );", ( str( psycopg2.extras.Inet( [ "8.8.8.8", "8.8.4.4" ] ) ) ) )
У меня ошибка TypeError: not all arguments converted during string formatting.
Согласно документы, похоже, что psycopg будет преобразовывать массив inet в список строк. Однако я не совсем уверен, как это работает наоборот. Может быть, вы можете попробовать cursor.execute( "INSERT INTO test( ip_list ) VALUES ( %s );", (['8.8.8.8'],)) для параметризованной вставки.
@ Scratch'N'Purr эта строка дает ошибку DETAIL: Array value must start with "{" or dimension information.
@MeghdeepRay: Используя sqlfiddle, это сработало. INSERT INTO test( ip_list ) VALUES ('{ 8.8.8.8, 8.8.4.4}');. Вам нужны фигурные скобки для обозначения массива. Заключите его в кавычки, чтобы получилась одна строка. Здесь - это документ, в котором объясняется, как использовать массивы.
@shahkalpesh Это определенно работает, но мне нужно, чтобы он работал с параметризованными входами.
@MeghdeepRay: cursor.execute( "INSERT INTO test( ip_list ) VALUES ('{ 8.8.8.8, 8.8.4.4}')"); - это помогает?






Я думаю, проблема в том, как вы форматируете строку и синтаксис вашего запроса.
Вы можете просто вставить запись, если запустите свой запрос следующим образом:
INSERT INTO itest( ip_list ) VALUES ( '{ 8.8.8.8 }' );
Или несколько значений:
INSERT INTO itest( ip_list ) VALUES ('{ 192.168.2.1, 120.12.25.26, 10.20.30.40, 156.223.122.252 }');
.
Чтобы отформатировать такой запрос в python, вы можете сделать что-то вроде этого:
cur.execute( "INSERT INTO itest( ip_list ) VALUES ( %s );" % ("'{ 200.8.8.200 }'"))
.
================================================== =============
Ответ на комментарий:
Я только что посмотрел на класс Inet(), и, похоже, он не возвращает правильное приведение для массивов (я не уверен, что мне здесь что-то не хватает, поправьте меня, если я ошибаюсь). Однако в качестве обходного пути я придумал это.
cur = conn.cursor()
cur.execute( "INSERT INTO itest( ip_list ) VALUES ( %s[] );", (Inet([ "8.8.8.8", "8.8.4.4" ]),))
conn.commit()
Как видите, я вручную добавил преобразование массива [] в тип inet.
Надеюсь, это поможет :) Не стесняйтесь спрашивать, есть ли у вас сомнения !!
Как это достигается с помощью параметризованного ввода через библиотеку psycopg2? Если мне нужно каждый раз вводить переменное количество IP-адресов?
@MeghdeepRay, пожалуйста, прочтите редактируемую часть моего ответа. Я его обновил.
Если вы вставляете в поле массива, не должно ли значение вставки быть чем-то вроде
array['8.8.8.8']::inet[]?