SQLAlchemy复合类型

时间:2015-04-14 12:04:17

标签: postgresql sqlalchemy psycopg2 compositetype

SQLAlchemy是否支持PostgreSQL的复合类型(http://www.postgresql.org/docs/devel/static/rowtypes.html)?我发现它有类似的东西(sqlalchemy.orm.composite),但就我所知,它对我的​​目的来说还不够好。

我想制作一个单独的类型,例如Amount valuecurrency,然后可以重复引用它,也可能多次引用它同一个班级:

class Transfer(base):
    __tablename__ = "transfer"
    source_amount = Column(Amount)
    target_amount = Column(Amount)

我见过的所有示例(例如this one)都要求我指定列的名称,这使得上述方法无法实现(列名称会发生​​冲突)。

此外,我宁愿每个金额有一列而不是两个(因为value没有currency真的没有意义,我宁愿数据库注意永远不要分离或混合它们)。似乎Postgres可以做到这一点,我只需要一种方法向SQLAlchemy解释我需要什么。我尝试阅读http://docs.sqlalchemy.org/en/latest/core/custom_types.html,但它似乎专注于扩充现有类型,而不是创建新的类型(我不知道在impl下要放什么)。

也许我应该放弃SQLAlchemy并直接与psycopg2通信?它具有psycopg2.extras.register_composite功能,但是一旦我这样做,我仍然不知道如何说服SQLAlchemy识别注册。我可能不得不以某种方式将光标从psycopg2传递给SQLAlchemy,但我不知道该怎么做。

1 个答案:

答案 0 :(得分:1)

sqlalchemy本身不支持postgresql复合类型。

但是,sqlalchemy_utils本身支持postgresql复合类型。

以下是他们的文档中的示例:

from collections import OrderedDict

import sqlalchemy as sa
from sqlalchemy_utils import CompositeType, CurrencyType

class Account(Base):
    __tablename__ = 'account'
    id = sa.Column(sa.Integer, primary_key=True)
    balance = sa.Column(
        CompositeType(
            'money_type',
            [
                sa.Column('currency', CurrencyType),
                sa.Column('amount', sa.Integer)
            ]
        )
    )

用法:

session.query(Account).filter(Account.balance.amount > 5000)