Список Python в PostgreSQL HSTORE через SQLAlchemy

#python #postgresql #sqlalchemy #psycopg2 #hstore

Вопрос:

Я хотел бы хранить диктанты Python, содержащие списки, в качестве объекта HSTORE в базе данных PostgreSQL с использованием SQLAlchemy. После моего урока за столом.

 from sqlalchemy.dialects.postgresql import HSTORE
from sqlalchemy import Column, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Data(Base):
    id = Column(String, primary_key=True)
    data = Column(HSTORE)
 

Я включаю свои пункты в следующий вопрос.

 data = Data(
    id='fancy_id',
    data={
        'foo': ['bar', 'bar']
    },
)

db.Session.add(scan)
db.Session.commit()
 

Это приводит к ОТКАТУ и возникновению следующего исключения.

 sqlalchemy.exc.DataError: (psycopg2.errors.ArraySubscriptError) wrong number of array subscripts

[SQL: INSERT INTO data (id, data) VALUES (%(id)s, %(data)s)]
[parameters: {'id': 'fancy_id', 'data': {'foo': ['bar', 'bar']}}]
 

Однако вставка работает без списка.

 data = Data(
    id='fancy_id',
    data={
        'foo': 'bar'
    },
)
 

Я следил за документацией PostgreSQL SQLAlchemy 1.4 и не могу найти примечание, указывающее на это ограничение. Я что-то упускаю? Как я могу хранить списки Python внутри объектов PostgreSQL HSTORE с помощью SQLAlchemy?

Заранее спасибо.

Ответ №1:

Честно говоря, для такого рода вещей json/jsonb было бы лучшим вариантом. Тогда у вас будет прямое сопоставление Python dict со списком с объектом JSON с массивом. Если вы хотите использовать hstore , то:

 create table hstore_test(id int, hs_fld hstore);
insert into hstore_test values (1, 'a=>1');
insert into hstore_test values (1, 'b=>"[1,2]"'::hstore);
select * from hstore_test ;
 id |    hs_fld    
---- --------------
  1 | "a"=>"1"
  1 | "b"=>"[1,2]"

--So for your example

data={
        'foo': "['bar', 'bar']"
    },