【问题标题】:Auto updating properties in sqlalchemysqlalchemy 中的自动更新属性
【发布时间】:2011-09-19 07:37:53
【问题描述】:

我有一个这样设置的 sqlalchemy 模型:

class Entry(Base):
    __tablename__ = 'entries'
    __table__ = Table('entries', Base.metadata,
            Column('id', Integer, primary_key=True, unique=True),
            Column('user_id', Integer, ForeignKey('users.id', onupdate="CASCADE", ondelete="RESTRICT")),
            Column('title', String(128)),
            Column('slug', String(128), index=True),
            Column('url', String(256), index=True),
            Column('entry', Text),
            Column('cached_entry', Text),
            Column('created', DateTime, server_default=text('current_timestamp')),
            Column('modified', DateTime, server_onupdate=text('current_timestamp')),
            Column('pubdate', DateTime),
            )

我想要的是,当我更新 entry 时,cached_entry 会重新生成,cached_entryentry 的降价解析版本。基本上我正在缓存降价解析的输出,这样我就不必在每次显示条目时都这样做。我尝试过使用@hybrid_method,但这似乎不起作用,因为它根本没有存储在数据库中。我有got it working on Google AppEngine,但我似乎无法弄清楚如何使用 SQLAlchemy 做同样的事情。

我真的不希望向所使用的类添加一个函数而不是模型中的名称,因为从应用程序的角度来看它更难强制执行,我不想意外错过某些东西。

【问题讨论】:

    标签: python properties sqlalchemy automatic-properties


    【解决方案1】:

    @hybrid_descriptor 当然是使用http://www.sqlalchemy.org/docs/orm/mapper_config.html#using-descriptors 中描述的形式来实现的。您分配给数据库映射属性,您可以使用不同的名称进行映射 - 因为您使用的是__table__,所以您可以使用如下形式:

    class Entry(Base):
        __table__ = ...
    
        _entry = __table__.c.entry
    
        @hybrid_property
        def entry(self):
            return self._entry
    
        @entry.setter
        def entry(self, value):
            self._entry = value
            self.cached_entry = markdown(value)
    

    另一种方法是使用 before_insert 和 before_update 事件在刷新时填充列 - 这是一种简单的方法,但缺点是您必须等待 flush() 才能发生。

    我认为“现场”最快的方法是使用@validates:

    from sqlalchemy.orm import validates
    
    class Entry(Base):
        __table__ = ...
    
        @validates('entry')
        def _set_entry(self, key, value):
            self.cached_entry = markdown(value)
            return value
    

    【讨论】:

    • 那是我断开连接的地方,我不知道当它没有像普通 ORM 模型那样声明而是使用 table 时如何创建一个 _entry。你已经为我解开了这个谜团,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    • 1970-01-01
    相关资源
    最近更新 更多