Как я могу хранить вложенные списки в Postgres
так, чтобы их можно было легко использовать в своей Python
программе позже?
Я планирую записать списки в базу данных один раз и использовать их много раз. Мне удалось сохранить вложенные списки в виде string
, но это не оптимально, я пытаюсь добиться этого с минимально возможной постобработкой, поэтому я предпочитаю выполнять больше предварительной работы для скорости/простоты использования. при получении позже.
Эти вложенные списки предназначены для целей макетирования, а не для плохой нормализации данных.
Вот что я пробовал на основе здесь:
В моей базе данных создана таблица с полем, которое поддерживает ARRAY
(я использую DBeaver, аннотация для ARRAY
— это подчеркивание перед текстом: _text
)
CREATE TABLE public.layout (
f_id int8 NULL,
layout _text NULL
);
При попытке этого:
insert into mpl_layout (f_id, layout)
values (7, ARRAY[["list_1"],["list_2"],["list_3"],["list_4"]]);
Я получаю сообщение об ошибке:
Ошибка SQL [42703]: ОШИБКА: столбец «list_1» не существует.
Добавление круглых скобок вокруг аргументов ARRAY
меняет только сообщение об ошибке:
insert into mpl_layout (f_id, layout)
values (7, ARRAY([["list_1"],["list_2"],["list_3"],["list_4"]]));
Ошибка SQL [42601]: ОШИБКА: синтаксическая ошибка на уровне «7» или около нее.
Я попробовал формат фигурных скобок '{}'
:
insert into mpl_mosaic_layout (figure_id, layout)
values (7, '{[["list_1"],["list_2"],["list_3"],["list_4"]]}');
И получил эту ошибку:
Ошибка SQL [22P02]: ОШИБКА: неверный литерал массива: "{[["list_1"],["list_2"],["list_3"],["list_4"]]}" Деталь: неожиданная элемент массива.
Что мне попробовать дальше?
@Ze'evBen-Tsvi Ваш комментарий верен, яйцо на моем лице -> Я должен был это увидеть. Пожалуйста, опубликуйте ответ в качестве ответа, и я приму.
1) Причина, по которой вы получаете ошибку, заключается в следующем: "list_1"
двойные кавычки предназначены для идентификаторов, поэтому Postgres думает, что вы имеете в виду имя столбца. См. Массивы 8.15.2. Ввод значения массива для примеров. 2) Если вы собираетесь использовать Python, используйте адаптацию списка psycopg2, чтобы она работала за вас. 3) В вашем последнем примере должны использоваться все фигурные скобки, см. ссылку «Ввод значения массива» в разделе 1).
Вставка массива с использованием обеих форм ввода ARRAY
:
CREATE TABLE public.layout (
f_id int8,
layout varchar[]
);
insert into layout values (1, ARRAY[['list_1'],['list_2'],['list_3'],['list_4']]);
insert into layout values (2, '{{"list_1"},{"list_2"},{"list_3"},{"list_4"}}');
select * from layout ;
f_id | layout
------+---------------------------------------
1 | {{list_1},{list_2},{list_3},{list_4}}
2 | {{list_1},{list_2},{list_3},{list_4}}
Вам нужно использовать одинарные кавычки с формой ARRAY[]
и двойные кавычки с формой string('{}')
здесь ВВОД ЗНАЧЕНИЯ МАССИВА: Также можно использовать синтаксис конструктора ARRAY: [...] Обратите внимание, что элементы массива являются обычными константами SQL или выражения; например, строковые литералы заключаются в одинарные кавычки, а не в двойные, как в литералах массива.
Также для конструкторов ARRAY: значения многомерного массива могут быть созданы с помощью вложенных конструкторов массива. Во внутренних конструкторах ключевое слово ARRAY можно опустить.
В Python с использованием psycopg2
:
import psycopg2
con = psycopg2.connect(dbname='test', user='postgres', port=5432)
cur = con.cursor()
array_list = [["list_1"],["list_2"],["list_3"],["list_4"]]
cur.execute("insert into layout values(%s, %s)", [3, array_list])
con.commit()
Вышеупомянутое использует psycopg2
адаптацию списка/массива, как описано здесь Адаптация списков.
Что приводит к:
select * from layout ;
f_id | layout
------+---------------------------------------
1 | {{list_1},{list_2},{list_3},{list_4}}
2 | {{list_1},{list_2},{list_3},{list_4}}
3 | {{list_1},{list_2},{list_3},{list_4}}
Я не проверял (поэтому не разместил это как ответ), согласно примеру в URL-адресе DBeaver, синтаксис больше похож на: значения (7, МАССИВ[МАССИВ["список_1"], МАССИВ[ "список_2"], МАССИВ["список_3"], МАССИВ["список_4"]]); Ключевое слово ARRAY присутствует перед каждым списком.