1

すべてのモデル (タイムスタンプ) で単純な機能を共有しようとしており、SQLA ドキュメントで説明されているように、「ベースの拡張」アプローチを使用しています。これまでのところ、私はこれをしました:

import sqlalchemy as sa
from datetime import datetime as dt

class EntityBase(object):

    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()

    id = sa.Column(sa.Integer, primary_key=True)
    last_update = sa.Column(sa.DateTime, default=dt.utcnow())

def update_entity(mapper, connection, target):
    target.last_update = dt.utcnow()


Entity = declarative_base(cls=EntityBase)

sa.event.listen(Entity, 'before_insert', update_entity)
sa.event.listen(Entity, 'before_update', update_entity)

私のモデルはすべてEntityクラスから派生しています。しかし、実行時に取得しますsqlalchemy.orm.exc.UnmappedClassError: Class 'sqlalchemy.ext.declarative.Base' is not mapped。私は何を間違っていますか?

更新 次のように単純な前処理を行うことで問題を回避しました。

def setupEntities():
    ...
    for cls in Entity.__subclasses__():
        listen(cls, 'before_insert', update_entity)
        listen(cls, 'before_update', update_entity)
    ...

...でも、正しい方法について聞きたいです。

4

1 に答える 1

1

ここで興味深いのは、上で行った方法がおそらくうまくいくはずだということです。便利でしょう。そのため、そのhttp://www.sqlalchemy.org/trac/ticket/2585のチケットを追加しました。

今のところ、これを行う方法は、Base とともに新しいマッピングのイベント リスナーを設定することです。

Entity = declarative_base(cls=EntityBase):

from sqlalchemy.orm import mapper
@event.listens_for(mapper, 'mapper_configured')
def set_events(mapper, class_):
   if issubclass(class_, Entity):
        listen(class_, 'before_update', update_entity)
        listen(class_, 'before_insert', update_entity)

実際、#2585 の機能を実装する場合、おそらくこれと非常によく似た方法で実装する必要があります。

于 2012-10-04T14:42:18.023 に答える