首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQLAlchemy中的信号或触发器

SQLAlchemy中的信号或触发器
EN

Stack Overflow用户
提问于 2009-08-03 12:54:49
回答 5查看 11.9K关注 0票数 17

SQLAlchemy是否有类似于Django的signal概念?基本上,当我预保存或后保存一些实体对象时,我想触发一些函数。谢谢。

编辑:我只需要SQLAlchemy中的django-signals的等价物。

EN

回答 5

Stack Overflow用户

发布于 2012-10-01 02:28:51

我想你正在寻找‘`ORM事件’。您可以在以下位置找到文档:

http://docs.sqlalchemy.org/en/latest/orm/events.html

票数 13
EN

Stack Overflow用户

发布于 2009-08-03 13:09:43

你并没有明确,你是在集成SQLAlchemy和Django,还是你只是想要SQLAlchemy中的django-signals的等价物。

如果你想要像post_save,pre_save,pre_delete等Django信号的等价物,我会参考你的页面,

sqlalchemy.orm.interfaces.MapperExtension

票数 6
EN

Stack Overflow用户

发布于 2009-08-03 15:22:57

您可能还需要考虑sqlalchemy.orm.SessionExtension

下面是我拼凑的一些代码,用来在一个实例上设置一个所有者id,并设置一个在pylons应用程序中完成这项工作的update_date。OrmExt类是所有魔术发生的地方。而init_model是你将其连接起来的地方。

代码语言:javascript
复制
import logging
import sqlalchemy as sa
from sqlalchemy import orm

from pylons import session

import datetime

log = logging.getLogger(__name__)

class ORMSecurityException(Exception):
    '''
    thrown for security violations in orm layer
    '''
    pass

def _get_current_user():
    log.debug('getting current user from session...')
    log.debug(session)
    return session['user'] 

def _is_admin(user):
    return False  


def set_update_date(instance):

    if hasattr(instance,'update_date'):
    instance.update_date = datetime.datetime.now()

def set_owner(instance):
    '''
    if owner_id, run it through the rules
    '''
    log.info('set_owner')
    if hasattr(instance, 'owner_id'):
    log.info('instance.owner_id=%s' % instance.owner_id)
    u = _get_current_user()
    log.debug('user: %s' % u.email)
    if not u:
        #anonymous users can't save owned objects
        raise ORMSecurityException()
    if instance.owner_id==None:
        #must be new object thus, owned by current user
        log.info('setting owner on object %s for user: %s' % (instance.__class__.__name__,u.email))
        instance.owner_id = u.id
    elif instance.owner_id!=u.id and not _is_admin(u):
        #if owner_id does not match user_id and user is not admin VIOLATION
        raise ORMSecurityException()
    else:
        log.info('object is already owned by this user')
        return #good to go
else:
    log.info('%s is not an owned object' % instance.__class__.__name__)
    return

def instance_policy(instance):
    log.info('setting owner for %s' % instance.__class__.__name__)
    set_owner(instance)
    log.info('setting update_date for %s' % instance.__class__.__name__)
    set_update_date(instance)


class ORMExt(orm.SessionExtension):
    '''
    attempt at managing ownership logic on objects
    '''
    def __init__(self,policy):
        self._policy = policy

    def before_flush(self,sqlsess,flush_context,instances):
        '''
        check all instances for owner_id==user.id
        '''
        try:
            for instance in sqlsess.deleted:
                try:
                    log.info('running policy for deleted %s' % instance.__class__.__name__)
                    self._policy(instance)
                except Exception,ex:
                    log.error(ex)
                    raise ex

            for instance in sqlsess.new:
                try:
                    log.info('running policy for new %s' % instance.__class__.__name__)
                    self._policy(instance)
                except Exception,ex:
                    log.error(ex)
                    raise ex

            for instance in sqlsess.dirty:
                try:
                    if sqlsess.is_modified(instance,include_collections=False,passive=True):
                        log.info('running policy for updated %s' % instance.__class__.__name__)
                        self._policy(instance)
                except Exception, ex:
                    log.error(ex)
                    raise ex

        except Exception,ex:
            sqlsess.expunge_all()
            raise ex

def init_model(engine):
    """Call me before using any of the tables or classes in the model"""
    sm = orm.sessionmaker(autoflush=True, autocommit=True, bind=engine,extension=ORMExt(instance_policy))
    meta.engine = engine
    meta.Session = orm.scoped_session(sm)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1222208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档