【问题标题】:SQLAlchemy default PostgreSQL ARRAY behaviorSQLAlchemy 默认 PostgreSQL ARRAY 行为
【发布时间】:2015-05-28 07:30:20
【问题描述】:

我有一个表,我正在使用 SQLAlchemy 表达式引擎创建并与之交互,我需要能够从 ARRAY 列中获取值作为 python tuple 而不是 list。由于ARRAY 列的构造函数允许您指定是否要将值作为元组,我最终只是将表反映在数据库之外,寻找ARRAY 列,将它们替换为具有适当的关键字参数,然后使用它来构造表达式。像这样:

from sqlalchemy import Table, Column, String, MetaData, select

def swapArrayColumns(table):
    new_cols = []
    for col in table.columns:
        if isinstance(col.type, ARRAY):
            new_cols.append(Column(col.name, ARRAY(String, as_tuple=True)))
        else:
        new_cols.append(Column(col.name, col.type))
    return new_cols

engine = create_engine('postgresql://localhost:5432/dbname')    
meta = MetaData()
table = Table('table_name', meta, autoload=True, autoload_with=engine)
new_cols = swapArrayColumns(table)

# delete old meta since we are re-mapping table
del meta
meta = MetaData()
new_table = Table('table_name', meta, *new_cols)

# Now I can use the new table object to generate expressions
sel = select([new_table]).where(new_table.c.foo == 'bar')
rows = list(engine.execute(sel))

由于这被大量使用,我想知道是否有更优雅的方式来完成同样的事情,也许是通过创建一个自定义的 sqlalchemy 方言来为我做这件事。我真正想要的是我的ARRAY 列默认返回为python tuples。

【问题讨论】:

    标签: python arrays postgresql sqlalchemy


    【解决方案1】:

    可以看看使用custom sqlalchemy type,像这样:

    from sqlalchemy.dialects.postgresql import ARRAY,
    class Tuple(types.TypeDecorator):
        impl = ARRAY
    
        def process_bind_param(self, value, dialect):
            return list(value)
    
        def process_result_value(self, value, dialect):
            return tuple(value)
    

    在模型本身中(使用声明性):

    class MyModel(Base):
        id = Column(Integer, primary_key=True)
        data = Column(Tuple)
    

    另一种方法可能是子类 ARRAY:

    from  sqlalchemy.dialects.postgresql import ARRAY as PG_ARRAY
    class ARRAY(PG_ARRAY):
        def __init__(self, *args, **kwargs):
            super(PG_ARRAY, self ).__init__(*args, *kwargs)
            self.as_tuple = True
    

    【讨论】:

    • 我想问题是表是动态创建的,(有时有数组列,有时没有),因此,我没有使用 SQLAlchemy 的 ORM 部分,只是表反射和 SQL 表达式生成器部分。理想的情况是在我创建用于连接数据库的engine 时覆盖它(这样我从数据库中获取的每个ARRAY 都变成了Python tuple),这就是我为什么认为Dialect 方法可能有效。
    • 不过,答案很好。只是为了一个稍微不同的问题;P
    • 子分类数组可能会起作用,请检查更新的答案。不过还没有测试过。
    • 我将如何使用它?是否可以将其注册为 postgresql 方言默认使用的全局事物?
    猜你喜欢
    • 2013-12-30
    • 2023-02-09
    • 1970-01-01
    • 2018-09-07
    • 2022-08-04
    • 2012-05-03
    • 2016-07-14
    • 2016-12-22
    • 1970-01-01
    相关资源
    最近更新 更多