blu*_*ank 10 python events model sqlalchemy
我正在尝试同时处理2件新事物,因此我们非常感谢您在简化和澄清方面的帮助.
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy import Column, Float, event
class TimeStampMixin(object):
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
created = Column(Float)
modified = Column(Float)
def __init__(self, created = None,
modified = None):
self.created = created
self.modified = modified
def create_time(mapper, connection, target):
target.created = time()
#def modified_time(mapper, connection, target):
# target.modified = time()
event.listen(TimeStampMixin, 'before_insert', create_time)
#event.listen(TimeStampMixin, 'before_update', modified_time)
Run Code Online (Sandbox Code Playgroud)
所以我想创建一个我可以在任何类中应用的mixin:
class MyClass(TimeStampMixin, Base):
etc, etc, etc
Run Code Online (Sandbox Code Playgroud)
此类继承在创建时创建时间戳并在更新时创建/修改时间戳的功能.
在导入时我收到此错误:
raise exc.UnmappedClassError(class_)
sqlalchemy.orm.exc.UnmappedClassError: Class 'db.database.TimeStampMixin' is not mapped
Run Code Online (Sandbox Code Playgroud)
aaaand我在这一点上很难过.
deB*_*ice 35
将侦听器附加到类方法中,它会将事件附加到子类.
class TimeStampMixin(object):
@staticmethod
def create_time(mapper, connection, target):
target.created = time()
@classmethod
def __declare_last__(cls):
# get called after mappings are completed
# http://docs.sqlalchemy.org/en/rel_0_7/orm/extensions/declarative.html#declare-last
event.listen(cls, 'before_insert', cls.create_time)
Run Code Online (Sandbox Code Playgroud)
Jef*_*ner 13
这是我要做的事情来监听before_insert事件:添加一个classmethod到您的TimeStampMixin注册当前类并处理设置创建时间.
例如
class TimeStampMixin(object):
# other class methods
@staticmethod
def create_time(mapper, connection, target):
target.created = time()
@classmethod
def register(cls):
sqlalchemy.event.listen(cls, 'before_insert', cls.create_time)
Run Code Online (Sandbox Code Playgroud)
这样,你可以:
你可以简单地使用它:
class MyMappedClass(TimeStampMixin, Base):
pass
MyMappedClass.register()
Run Code Online (Sandbox Code Playgroud)
简单,非常清晰,没有魔力,但仍然像你想要的那样封装.
现代 SqlAlchemy 中最好的方法是将@listens_for装饰器与propagate=True.
from datetime import datetime
from sqlalchemy import Column, Float
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.event import listens_for
class TimestampMixin():
@declared_attr
def created(cls):
return Column(DateTime(timezone=True))
@listens_for(TimeStampMixin, "init", propagate=True)
def timestamp_init(target, args, kwargs):
kwargs["created"] = datetime.utcnow()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4251 次 |
| 最近记录: |