2012-01-18 125 views
9

我在每个模型中都有字段created_by和updated_by。这些字段会自动填充sqlalchemy.event.listen(以前称为MapperExtension)。对于每个模型,我写: 所有模型的SQLAlchemy“event.listen”

event.listen(Equipment, 'before_insert', get_created_by_id) 
event.listen(Equipment, 'before_update', get_updated_by_id) 

当模型是大量的代码变得丑陋。是否可以将event.listen立即应用于所有模型或几个?

UPD:我想这样做:

import pylons 
from sqlalchemy import event, sql 
from sqlalchemy import Table, ForeignKey, Column 
from sqlalchemy.databases import postgresql 
from sqlalchemy.schema import UniqueConstraint, CheckConstraint 
from sqlalchemy.types import String, Unicode, UnicodeText, Integer, DateTime,\ 
          Boolean, Float 
from sqlalchemy.orm import relation, backref, synonym, relationship 
from sqlalchemy import func 
from sqlalchemy import desc 
from sqlalchemy.orm.exc import NoResultFound 

from myapp.model.meta import Session as s 
from myapp.model.meta import metadata, DeclarativeBase 

from pylons import request 

def created_by(mapper, connection, target): 
    identity = request.environ.get('repoze.who.identity') 
    if identity: 
     id = identity['user'].user_id 
     target.created_by = id 

def updated_by(mapper, connection, target): 
    identity = request.environ.get('repoze.who.identity') 
    if identity: 
     id = identity['user'].user_id 
     target.updated_by = id 

from sqlalchemy.ext.declarative import declared_attr 
from sqlalchemy.ext.declarative import has_inherited_table 

class TestMixin(DeclarativeBase): 
    __tablename__ = 'TestMixin' 

    id = Column(Integer, autoincrement=True, primary_key=True) 

event.listen(TestMixin, 'before_insert', created_by) 
event.listen(TestMixin, 'before_update', updated_by) 

class MyClass(TestMixin): 
    __tablename__ = 'MyClass' 
    __mapper_args__ = {'concrete':True} 

    id = Column(Integer, autoincrement=True, primary_key=True) 

    created_by = Column(Integer, ForeignKey('user.user_id', 
         onupdate="cascade", ondelete="restrict")) 

    updated_by = Column(Integer, ForeignKey('user.user_id', 
         onupdate="cascade", ondelete="restrict")) 

当我添加一个新的MyClass的对象我有CREATED_BY =无。如果我为MyClass创建event.listen一切正常。怎么了?

+0

我在这里找到了答案http://stackoverflow.com/questions/12753450/ sqlalchemy-mixins-and-event-listener – uralbash 2014-04-16 14:09:25

回答

9

继承所有模型从基类和订阅的基类:

event.listen(MyBaseMixin, 'before_insert', get_created_by_id) 
event.listen(MyBaseMixin, 'before_update', get_updated_by_id) 

查看更多关于Mixin and Custom Base Classes

+0

这是我的代码http://pastebin.com/vzsR5hde我试图使用Mixin但出现错误:sqlalchemy.exc.InvalidRequestError:表'ttt'已经为此定义元数据实例。指定'extend_existing = True'来重新定义现有Table对象上的选项和列。 – uralbash 2012-01-23 07:29:35

+0

@uralbash你的'LogMixin'实际上不是一个混合类,而是一个映射的“模型”类,因为它继承自'DeclarativeBase'。现在,您映射使用相同声明表的其他'Net'类,但映射更多列。 – 2012-01-27 16:01:26

+1

在0.9.6中这似乎不起作用(不再?)。 SQLAlchemy将允许我将侦听器绑定到我的基本mixin类,但侦听器永远不会被调用。如果我将同一个侦听器添加到特定的模型类,它会被调用。 (是的,这是一个实际的混合类:)) – mmitchell 2015-02-13 19:22:36