【问题标题】:PostgreSQL multidimensional arrays in SQLAlchemySQLAlchemy 中的 PostgreSQL 多维数组
【发布时间】:2012-03-15 22:33:16
【问题描述】:

我在 Debian Squeeze 上使用 SQLAlchemy 0.6.3 和 PostgreSQL 8.4。我想要一个表,其中一列在 PostgreSQL 中存储一些东西,在 Python 中显示为整数列表或整数元组的元组的列表。例如

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

在下面的示例中,该列是model。我认为一种合理的方法可能是将内容存储为 PG 二维表,在 PG 中看起来像 integer[][]。我不知道 SQLA 会以什么形式将它返回给 Python,但我希望它类似于元组的元组。

但是,我不知道如何告诉 SQLA 给我一个二维整数数组。 documentation for sqlalchemy.dialects.postgresql.ARRAY 表示

item_type – 此数组的项目的数据类型。注意 维度在这里是无关紧要的,所以多维数组像 INTEGER[][],构造为 ARRAY(Integer),而不是 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
);

当然,这是不对的。我错过了什么?

【问题讨论】:

  • 如果您要做很​​多此类事情,那么您可能不会考虑天气关系数据库是您的最佳选择。
  • @Mark:我不关注。很多什么样的东西?
  • 如果您尝试保存大量数组数组或地图映射等,那么您可能不会将支持该概念的数据库视为第一类,例如 redis
  • @Mark:好的,我明白了。不,它只是一些信息的方便占位符。没有什么很重要的。
  • 如果您其余的大部分数据都很好并且关系很好,那么我想它会引起人们的注意。

标签: python multidimensional-array sqlalchemy


【解决方案1】:

我在这里回答这个问题,因为 Mike Bayer 在 sqlalchemy 用户上回答了这个问题。

请参阅 sqlalchemy-user 上的 thread,Mike Bayer 对此问题作出了回应。正如 Mike 澄清的那样,正如我在阅读 PG 文档时错过的那样,PG 实际上并没有强制执行数组维度,SQLA 也没有。所以,可以写integer[][],但PG 并没有将其与integer[] 区别对待。特别是,PG 和 SQLA 都将接受任何维度的数组表达式。我不确定为什么会这样。正如 Mike 所引用的,PG Arrays documentation

当前的实现不强制声明的数量 尺寸。特定元素类型的数组都是 被认为是同一类型,无论大小或数量 方面。因此,在中声明数组大小或维数 CREATE TABLE 只是文档;它不影响运行时 行为。

另见他打开的ticket。 看起来这是在 SQLA 级别强制执行维度。

【讨论】:

    【解决方案2】:

    我试过了

    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 他们提到了。

    但是,当前实现忽略任何提供的数组大小限制,即行为与未指定长度的数组相同。

    因此,如果您没有声明任何内容,那么它将是您想要的数组。

    【讨论】:

    • 嗨拉法达。您在正确的范围内,但引用了错误的文档。问题是关于尺寸,而不是数组大小限制。请参阅上面的更新。由于您是唯一回复的人,如果您修复您的答案,我会接受它。 :-)
    • 您需要通过 sqlalchemy 声明 integer[][] 而不是 integer[]。但现在它超出了我对 sqlalchemy 的了解:)。
    • 对不起,我不关注这个评论。
    猜你喜欢
    • 2016-03-28
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 2015-07-03
    相关资源
    最近更新 更多