2012-03-15 2 views
7

Я использую SQLAlchemy 0.6.3 с PostgreSQL 8.4 при сжатии Debian. Я хочу таблицу, в которой один столбец хранит что-то в PostgreSQL, который отображается в Python в виде списка целых списков или кортежей целых кортежей. Например.Многомерные массивы PostgreSQL в SQLAlchemy

((1,2), (3,4), (5,6,7)) 

В приведенном ниже примере колонка model. Я думал, что разумный подход может состоять в том, чтобы хранить материал как таблицу размеров PG 2, которая в PG выглядит как integer[][]. Я не знаю, в какой форме SQLA вернет это на Python, но я надеюсь, что это что-то вроде кортежа кортежей.

Однако я не могу понять, как сказать SQLA, чтобы дать мне двумерный массив Integer. documentation для sqlalchemy.dialects.postgresql.ARRAY говорит

item_type - тип данных элементов этого массива. Обратите внимание, что размерность здесь не имеет значения, поэтому многомерные массивы типа INTEGER [] [] построены как ARRAY (целое число), а не как ARRAY (ARRAY (Integer)) или такие. Отображение типа отображается на лету.

К сожалению, я не знаю, что это значит. Как может отображаться тип отображения на лету? Он должен создать правильный DDL. Мое первое и единственное предположение, как это сделать, было бы ARRAY(ARRAY(Integer)). В настоящее время я

crossval_table = Table(
     name, meta, 
     Column('id', Integer, primary_key=True), 
     Column('created', TIMESTAMP(), default=now()), 
     Column('sample', postgresql.ARRAY(Integer)), 
     Column('model', postgresql.ARRAY(Integer)), 
     Column('time', Float), 
     schema = schema, 

Это создает следующий DDL

CREATE TABLE crossval (
    id integer NOT NULL, 
    created timestamp without time zone, 
    sample integer[], 
    model integer[], 
    "time" double precision 
); 

, который не является, конечно, прав. Что мне не хватает?

+0

Если вы собираетесь делать много таких вещей, тогда вы можете подумать о том, что реляционный db - лучший вариант для вас. – Mark

+0

@Mark: Я не следую. Много чего? –

+0

Если вы пытаетесь сохранить множество массивов массивов или карт карт и т. Д., Тогда вы можете взглянуть на базу данных, которая поддерживает эту концепцию как 1-й класс, например redis – Mark

ответ

3

Я отвечаю на это здесь, так как Майк Байер ответил на этот вопрос на пользователей sqlalchemy.

См. thread на sqlalchemy-пользователя, где Майк Байер отвечает на этот вопрос. Как пояснил Майк, и, как я пропустил при чтении документации PG, PG фактически не применяет размеры массива, а также SQLA. Таким образом, можно написать integer[][], но PG не относится к нему иначе, чем от integer[]. В частности, как PG, так и SQLA будут принимать выражение массива любого измерения. Я не знаю, почему это так. Как цитирует Майк, то PG Arrays documentation говорит

Текущая реализация не обеспечивает заявленное количество размеров либо.Массивы определенного типа элемента - все считаются однотипными, независимо от размера или количества измерений . Итак, объявление размера массива или количества измерений в CREATE TABLE - это просто документация; это не влияет на поведение во время работы .

См. Также ticket он открыл. Похоже, что это необходимо для измерения размеров на уровне SQLA.

4

Я попробовал этот

from sqlalchemy import create_engine 
from sqlalchemy.orm import sessionmaker 

engine = create_engine('postgresql://:5432/test', echo=True) 

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.dialects import postgresql 

Base = declarative_base() 


from sqlalchemy import Column, Integer, String 

class User(Base): 
    __tablename__ = 'users' 

    id = Column(Integer, primary_key=True) 
    name = Column(String) 
    sample = Column(postgresql.ARRAY(Integer)) 


Base.metadata.create_all(engine) 

Session = sessionmaker(engine) 
s = Session() 

a = User() 
a.name='test' 
a.sample = [[1,2], [3,4]] 
s.add(a) 
s.commit() 

Я думаю, что это решит вашу проблему. Потому что в doc они упоминают.

Однако текущая реализация игнорирует любые заданные пределы размера массива, то есть поведение такое же, как для массивов неопределенной длины.

Так что если вы не заявляете ничего, это будет массив, который вы хотите.

+0

Hi Lafada. Вы были в правильном шаре, но процитировали неправильную документацию. Вопрос касался размеров, а не ограничений размера массива. См. Мое обновление выше. Поскольку вы единственный человек, отвечающий, если вы исправите свой ответ, я приму его. :-) –

+0

Вам нужно объявить 'integer [] []' вместо 'integer []' по sqlalchemy. Но теперь это из моих знаний для sqlalchemy :). – Nilesh

+0

Извините, я не следую этому комментарию. –

Смежные вопросы