2012-01-18 17 views
9

Her modelde created_by ve updated_by alanları var. Bu alanlar otomatik olarak sqlalchemy.event.listen (eskiden MapperExtension) ile doldurulur. Her model için yazıyorum: Model kod çok oldu Tüm modeller için SQLAlchemy "event.listen"

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

çirkin olur. Event.listen'i hemen tüm modellere veya birkaçına uygulamak mümkün mü?

UPD: Ben bunu yapmaya çalışıyorum:

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")) 

Yeni Sınıfım eklemek Ben created_by = Hiçbiri sahip çıkıyorlar. MyClass için event.listen oluşturursam her şey yolunda. Sorun nedir? temel sınıfından

+0

gör http://stackoverflow.com/questions/12753450/ sqlalchemy-mixins-and-event-dinleyici – uralbash

cevap

9

devral tüm modelleri ve bu temel sınıf abone:

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

Cevabı burada buldum daha Mixin and Custom Base Classes

+0

Bu benim kod http://pastebin.com/vzsR5hde Mixin kullanmaya çalışıyorum ama bir hata: sqlalchemy.exc.InvalidRequestError: Tablo 'ttt' zaten bunun için tanımlanmış MetaData örneği. Mevcut bir Table nesnesindeki seçenekleri ve sütunları yeniden tanımlamak için 'extend_existing = True' değerini belirtin. – uralbash

+0

@uralbash 'LogMixin' tablonuz aslında bir karışım sınıfı değil, “DeclarativeBase” 'den miras aldığı için haritalanmış bir “model” sınıfı değildir. Şimdi aynı bildirilen tabloyu kullanan diğer "Net" sınıfını, ancak daha fazla sütun eşleştirin. –

+1

Bu, artık çalışmıyor (0.9). SQLAlchemy, temel mixin sınıfına bir dinleyici bağlayamama izin verecek, ancak dinleyici asla çağrılmadı. Aynı dinleyiciyi belirli bir model sınıfına eklerseniz, çağrılır. (Ve evet, gerçek bir karışım sınıfı :)) – mmitchell