首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在sqlachemy.orm.synonym中使用描述符

如何在sqlachemy.orm.synonym中使用描述符
EN

Stack Overflow用户
提问于 2014-04-23 04:13:13
回答 2查看 990关注 0票数 1

我有这样的代码可以正常工作:

代码语言:javascript
复制
def get_timestamp(ts):
    return datetime.utcfromtimestamp(ts)

def set_timestamp(dt):
    return time.mktime(dt.timetuple())

class Group(Base):
    __tablename__ = 'group'
    _created = Column('created', Integer, nullable=False)

    @property
    def created(self):
        return get_timestamp(self._created)
    @created.setter
    def created(self, value):
        self._created = set_timestamp(value)

我想要一些这样的代码,但它不起作用:

代码语言:javascript
复制
created = synonym('_created',
                  descriptor=property(get_timestamp,
                                      set_created))

因为它总是作为第一个param在self中传递。

我想在我的项目中使用get_timestampset_timestamp。所以,我不打算让它们成为类的方法,而是独立的函数。

我怎样才能做到这一点?

编辑:我会选择Option2,并且仍然接受其他答案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-23 06:54:49

选项-1:下面的代码应该可以工作(您不需要有一个类来定义self):

代码语言:javascript
复制
def pget_timestamp(self):
    return datetime.utcfromtimestamp(self._created)

def pset_timestamp(self, dt):
    self._created = time.mktime(dt.timetuple())

class Group(Base):
    __tablename__ = 'group'
    id = Column(Integer, primary_key=True)
    _created = Column('created', Integer, nullable=False)

    created = synonym(_created,
            descriptor=property(pget_timestamp, pset_timestamp),
            )

选项-2:如果在许多类上确实需要相同的选项,则使用Mixins

代码语言:javascript
复制
from sqlalchemy.ext.declarative import declared_attr
class _CreatedMixin(object):
    _created = Column('created', Integer, nullable=False)

    def pget_timestamp(self):
        return datetime.utcfromtimestamp(self._created)

    def pset_timestamp(self, dt):
        self._created = time.mktime(dt.timetuple())

    @declared_attr
    def created(cls):
        return synonym('_created',
            descriptor=property(cls.pget_timestamp, cls.pset_timestamp),
            )


class Group(_CreatedMixin, Base):
    # @note: adding *_CreatedMixin* to bases defines both the column and the synonym
    __tablename__ = 'group'
    id = Column(Integer, primary_key=True)

或者,如果这是针对 all 您的类,则可以将_CreatedMixin作为所有模型的基类:

代码语言:javascript
复制
Base = declarative_base(engine, cls=_CreatedMixin)
class Group(Base):
    __tablename__ = 'group'
    id = Column(Integer, primary_key=True)

选项-3:您可以使用Hybrid Attributes执行上述任何操作

注意:使您的set/get函数同步:要么两者都使用,要么使用启用UTC的功能。目前(除非您在UTC-0中),将一个值设置为created将不会返回相同的值。

票数 1
EN

Stack Overflow用户

发布于 2014-05-14 04:07:13

我现在使用的是不同的实现。这与原来的标题无关,但如果你需要的话。

使用 sqlalchemy.types.TypeDecoratorDefining a table with sqlalchemy with a mysql unix timestamp

代码语言:javascript
复制
class UTCTimestampType(TypeDecorator):
    impl = Integer

    def process_bind_param(self, value, dialect):
        if value is None:
            return None  # support nullability
        elif isinstance(value, datetime):
            return int(time.mktime(value.timetuple()))
        raise ValueError("Can operate only on datetime values. Offending value type: {0}".format(type(value).__name__))

    def process_result_value(self, value, dialect):
        if value is not None:  # support nullability
            return datetime.fromtimestamp(float(value))

class ModelA(Base):
    __tablename__ = 'model_a'
    id = Column(Integer, primary_key=True)
    created = Column(UTCTimestampType, nullable=False)

关于alembic的问题。Alembic: How to migrate custom type in a model?

代码语言:javascript
复制
# manually change the line
sa.Column('created', sa.UTCTImestampType(), nullable=False),
# to
sa.Column('created', sa.Integer(), nullable=False),
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23234601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档