SQLAlchemy列名和属性冲突

时间:2014-07-09 18:28:50

标签: python sqlalchemy

我有一个表模式" project_table"使用名为" status"的列。 问题是,我想覆盖并包装"状态"具有project.status属性的列,它将包装状态(' str')以方便其他未在此处显示的情况。

基本上我想这样做:

project = Session().query( Project ).filter_by( id=ID ).one()
print project.status #> will give <Status('act')> and not 'act'

但是,由于专栏(&#39;状态&#39;)已经创建了一个“状态”&#39;属性,我不能很好地覆盖它。所以我徘徊如何干净利落地做到这一点? 干净利落地意味着没有调整列或属性名称(列(&#39;状态_&#39;)或project.status_)

# Import
from sqlalchemy import Table, MetaData, Column, String, Enum, Integer

project_table   = Table('project', metadata,
                    Column('id', Integer, primary_key=True),
                    Column('name', String(32), nullable=False),
                    Column('status', Enum(u'act', u'dis'), default=u'act'))

metadata = MetaData()
Base = declarative_base()

# Project ORM class
class Project(Base):
    __table__ = project_table

    def __init__(self, **columns):
        super(Project, self).__init__(**columns)

    @property
    def status(self):
        '''Return status instance
        '''
        if not hasattr(self, '__status'):
            self.__status = Status(self.status)
        return self.__status

# Status wrapper class
class Status(str):
    '''Status layer of friendliness.
    '''

    MAP  = {'act'   : 'active',
            'dis'   : 'disabled' }

    def __init__(self, status_str ):

        self.__status   = status_str
        self.__nicename = ''
        self.__codename = ''

        for nicename, codename in Status.MAP.iteritems():

            if self.__status in [ nicename, codename ]:
                self.__nicename = nicename
                self.__codename = codename

    def __eq__(self, other):
        if self.__status == other:
            return True
        elif self.nicename() == other:
            return True
        else:
            return False

    def nicename(self):
        '''Return full name.
        '''
        return self.__nicename

    def codename(self):
        '''Return short/code name.
        '''
        return self.__codename

2 个答案:

答案 0 :(得分:3)

查看hybrid attributes,这可能会做你想要的,但老实说,隐藏这样的列名不是&#34;清洁&#34;或良好的编码实践。这令人困惑。

我的$ 0.02只是重命名列或重命名您尝试使用的属性。

答案 1 :(得分:0)

看起来您可以使用Sql Alchemy的“reconstructor”设置默认值,因为对象是从数据库加载的。

from sqlalchemy import orm

class Project(Base):
        __table__ = project_table

        def __init__(self, **columns):
            super(Project, self).__init__(**columns)

        @orm.reconstructor
        def init_on_load(self):
            # set status defaults here