Python SQLAlchemy:如何向自定义基类添加公共映射逻辑(使用声明式映射)?

Python SQLAlchemy:如何向自定义基类添加公共映射逻辑(使用声明式映射)?,python,sqlalchemy,Python,Sqlalchemy,我有一个项目,其中每个表都有一些公共字段,例如status,我想将它们全部别名。是否可以在不向每个类手动添加别名的情况下执行此操作?例如,以下是我现在拥有的: from core import foo_table, bar_table, Status Base = declarative_base() def CustomBase(object): @property def status(self): return Status(self._status) .

我有一个项目,其中每个表都有一些公共字段,例如status,我想将它们全部别名。是否可以在不向每个类手动添加别名的情况下执行此操作?例如,以下是我现在拥有的:

from core import foo_table, bar_table, Status 

Base = declarative_base()

def CustomBase(object):
   @property
   def status(self):
      return Status(self._status)
  ...

def Foo(Base, CustomBase):
   __table__ = foo_table
   _status = foo_table.c.status
   ...


def Bar(Base, CustomBase):
   __table__ = bar_table
   _status = bar_table.c.status
   ...
理想情况下,我希望能够在CustomBase上而不是在Foo和Bar中设置我的_状态别名,或者设置我的项目,以便在加载扩展CustomBase的类时添加别名。这是可能的,还是我试图以错误的方式来完成?我知道如果我重命名数据库中的status字段或CustomBase中的status属性,我可以让它工作,但如果可能的话,我更愿意避免这种情况,因为它们都是同一事物的表示,并且不需要通过代码直接访问枚举值


谢谢

您最好的选择可能是创建一个自定义列类型,该类型使Enum能够转换为您自己的Status类。请参阅以获取完整的参考资料。下面是您的
核心
模块的草稿,具体代码多少取决于您的情况

# core module

import sqlalchemy.types as types

class DBStatus (types.TypeDecorator):

    impl = types.Enum

    # what should happen with Status objects on the way into the table
    def process_bind_param(self, value, dialect):
        if value is None:
            return value
        return str(value)  # if Status has a __str__ or __repr__ method

    # what should happen with Enum objects on the way out of the table
    def process_result_value(self, value, dialect):
        if value is None:
            return value
        return Status(value)

foo_table = Table(
    'foo',
    MetaData(),
    Column('status', DBStatus('OK', 'Error')),
    # ...
)
在此之后,您不必再在模块中使用映射执行任何特殊操作:

# module with the mappings

Base = declarative_base()

class Foo (Base):
    __table__ = foo_table
    # ...
事实上,就状态列而言,它非常简单,您也可以使用完整的声明性映射

# everything in one module

class DBStatus (types.TypeDecorator):

    # same as above

Base = declarative_base()

class Foo (Base):
    status = Column(DBStatus('OK', 'Error'))
    # ...

你到底想达到什么目的?您是否只希望每个声明性模型都有一个
状态
字段?或者“别名”是指一些特殊的内容,例如所有那些
status
字段都应该引用一组公共对象?我的每个DB表都有一个名为status的枚举字段,但在代码中,我希望通过status类与之交互。我只需要原始状态值来初始化我的状态对象,这就是为什么我不确定这是否是正确的方法。可能我可以在某个地方钩住某个事件,或者对列类型做一些自定义操作,但我对SQLAlchemy非常陌生,代码示例中的解决方案是我唯一可以使用的解决方案。但是我不喜欢将别名(“\u status=bar\u table.c.status”)复制粘贴到每个类中,所以我想知道是否有更好的方法。