Как правильно вставить массив Post of Array в Postgresql с помощью Python (библиотека psycopg2)

1

Я получал эту ошибку последовательно, пытаясь вставить в массив типа 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: 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.

  • 0
    Если вы вставляете в поле массива, не должно ли значение вставки быть чем-то вроде array['8.8.8.8']::inet[] ?
  • 0
    Согласно документации , похоже, что psycopg приведёт массив inet к списку строк. Тем не менее, я не слишком уверен, как это работает наоборот. Возможно, вы можете попробовать cursor.execute( "INSERT INTO test( ip_list ) VALUES ( %s );", (['8.8.8.8'],)) для параметризованной вставки.
Показать ещё 4 комментария
Теги:
database
psycopg2

1 ответ

1
Лучший ответ

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

Вы можете просто вставить запись, если вы выполните свой запрос следующим образом:

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()

Как вы можете видеть, я вручную добавил массив casting [] к типу inet.

Надеюсь, что это поможет :) Не стесняйтесь спрашивать, есть ли у вас какие-либо сомнения!

  • 0
    Как это достигается с помощью параметризованного ввода через библиотеку psycopg2? Нужно ли вводить переменное количество IP-адресов каждый раз?
  • 0
    @MeghdeepRay, пожалуйста, смотрите часть моего ответа для редактирования. Я обновил это.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню