2012-03-15 34 views
7

Estoy usando SQLAlchemy 0.6.3 con PostgreSQL 8.4 en Debian squeeze. Quiero una tabla donde una columna almacene algo en PostgreSQL que aparezca en Python como una lista de listas enteras o tuplas de tuplas enteras. P.ej.Arrays multidimensionales PostgreSQL en SQLAlchemy

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

En el siguiente ejemplo, esa columna es model. Pensé que un enfoque razonable podría ser almacenar cosas como una tabla PG 2 dimensional, que en PG se parece al integer[][]. No sé en qué forma SQLA devolverá esto a Python, pero espero que sea algo así como una tupla de tuplas.

Sin embargo, no puedo entender cómo decirle a SQLA que me proporcione una matriz de enteros bidimensional. El documentation para sqlalchemy.dialects.postgresql.ARRAY dice

item_type - El tipo de datos de elementos de esta matriz. Tenga en cuenta que la dimensionalidad es irrelevante aquí, por lo que las matrices multidimensionales como INTEGER [] [], se construyen como ARRAY (Entero), no como ARRAY (ARRAY (Entero)) o similar. El mapeo tipo se da cuenta sobre la marcha.

Lamentablemente, no tengo idea de lo que eso significa. ¿Cómo puede el mapeo tipo resolver esto sobre la marcha? Necesita crear el DDL correcto. Mi primera y única suposición de cómo hacer esto habría sido ARRAY(ARRAY(Integer)). Actualmente tengo

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, 

Esto crea la siguiente DDL

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

lo cual no es cierto, por supuesto. ¿Qué me estoy perdiendo?

+0

Si va a hacer mucho de este tipo de cosas, entonces puede considerar el clima un DB relacional es la mejor opción para usted. – Mark

+0

@Mark: No sigo. Mucho de qué tipo de cosas? –

+0

Si intenta persistir en una gran cantidad de matrices de matrices o mapas de mapas, etc., puede que busque una base de datos que admita ese concepto como una 1ra clase, por ejemplo, redis – Mark

Respuesta

3

Estoy respondiendo esto aquí, ya que Mike Bayer respondió a esta pregunta en usuarios de sqlalchemy.

Vea el thread en sqlalchemy-usuario donde Mike Bayer responde a esta pregunta. Mientras Mike aclaraba, y como me perdí al leer la documentación de PG, PG no hace cumplir las dimensiones de la matriz, ni tampoco SQLA. Por lo tanto, uno puede escribir integer[][], pero PG no lo trata de manera diferente a integer[]. En particular, tanto PG como SQLA aceptarán una expresión de matriz de cualquier dimensión. No estoy seguro de por qué este es el caso. Citado por Mike, el PG Arrays documentation dice

La implementación actual no hace cumplir el número declarado de dimensiones tampoco.Las matrices de un tipo de elemento particular son todas consideradas del mismo tipo, independientemente del tamaño o el número de dimensiones . Por lo tanto, declarar el tamaño de la matriz o el número de dimensiones en CREATE TABLE es simplemente documentación; no afecta el comportamiento en tiempo de ejecución .

Vea también el ticket que abrió. Parece que esto es para hacer cumplir las dimensiones en el nivel SQLA.

4

yo probamos este

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

Creo que esto va a resolver su problema. Porque en doc mencionan.

Sin embargo, la implementación actual ignora cualquier límite de tamaño de matriz proporcionado, es decir, el comportamiento es el mismo que para las matrices de longitud no especificada.

Así que si no declaras nada, entonces será la matriz que quieras.

+0

Hola Lafada. Usted estaba en el estadio correcto, pero citó la documentación incorrecta. El problema era sobre las dimensiones, no los límites de tamaño de la matriz. Ver mi actualización arriba. Como usted es la única persona a quien responder, si corrige su respuesta, la aceptaré. :-) –

+0

Debe declarar 'entero [] []' en lugar de 'entero []' por sqlalchemy. Pero ahora está fuera de mi conocimiento para sqlalchemy :). – Nilesh

+0

Lo siento, no sigo este comentario. –