Python sqlalchemy.event.listen() Examples

The following are 30 code examples of sqlalchemy.event.listen(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module sqlalchemy.event , or try the search function .
Example #1
Source File: events.py    From pyRevit with GNU General Public License v3.0 6 votes vote down vote up
def _listen(cls, event_key, raw=False, propagate=False, **kw):
            target, identifier, fn = \
                event_key.dispatch_target, event_key.identifier, event_key.fn

            if target.class_ in target.all_holds:
                collection = target.all_holds[target.class_]
            else:
                collection = target.all_holds[target.class_] = {}

            event.registry._stored_in_collection(event_key, target)
            collection[event_key._key] = (event_key, raw, propagate)

            if propagate:
                stack = list(target.class_.__subclasses__())
                while stack:
                    subclass = stack.pop(0)
                    stack.extend(subclass.__subclasses__())
                    subject = target.resolve(subclass)
                    if subject is not None:
                        # we are already going through __subclasses__()
                        # so leave generic propagate flag False
                        event_key.with_dispatch_target(subject).\
                            listen(raw=raw, propagate=False, **kw) 
Example #2
Source File: test_reflection.py    From planespotter with MIT License 6 votes vote down vote up
def define_views(cls, metadata, schema):
        for table_name in ('users', 'email_addresses'):
            fullname = table_name
            if schema:
                fullname = "%s.%s" % (schema, table_name)
            view_name = fullname + '_v'
            query = "CREATE VIEW %s AS SELECT * FROM %s" % (
                view_name, fullname)

            event.listen(
                metadata,
                "after_create",
                DDL(query)
            )
            event.listen(
                metadata,
                "before_drop",
                DDL("DROP VIEW %s" % view_name)
            ) 
Example #3
Source File: events.py    From planespotter with MIT License 6 votes vote down vote up
def _listen(cls, event_key, propagate=True, **kw):
        target, identifier, fn = \
            event_key.dispatch_target, event_key.identifier, \
            event_key._listen_fn

        def listen(target_cls, *arg):
            listen_cls = target()
            if propagate and issubclass(target_cls, listen_cls):
                return fn(target_cls, *arg)
            elif not propagate and target_cls is listen_cls:
                return fn(target_cls, *arg)

        def remove(ref):
            key = event.registry._EventKey(
                None, identifier, listen,
                instrumentation._instrumentation_factory)
            getattr(instrumentation._instrumentation_factory.dispatch,
                    identifier).remove(key)

        target = weakref.ref(target.class_, remove)

        event_key.\
            with_dispatch_target(instrumentation._instrumentation_factory).\
            with_wrapper(listen).base_listen(**kw) 
Example #4
Source File: events.py    From planespotter with MIT License 6 votes vote down vote up
def _listen(cls, event_key, raw=False, propagate=False, **kw):
            target, identifier, fn = \
                event_key.dispatch_target, event_key.identifier, event_key.fn

            if target.class_ in target.all_holds:
                collection = target.all_holds[target.class_]
            else:
                collection = target.all_holds[target.class_] = {}

            event.registry._stored_in_collection(event_key, target)
            collection[event_key._key] = (event_key, raw, propagate)

            if propagate:
                stack = list(target.class_.__subclasses__())
                while stack:
                    subclass = stack.pop(0)
                    stack.extend(subclass.__subclasses__())
                    subject = target.resolve(subclass)
                    if subject is not None:
                        # we are already going through __subclasses__()
                        # so leave generic propagate flag False
                        event_key.with_dispatch_target(subject).\
                            listen(raw=raw, propagate=False, **kw) 
Example #5
Source File: validator.py    From Flask-Validator with Mozilla Public License 2.0 6 votes vote down vote up
def __init__(self, field, allow_null, throw_exception, message,
                 interpolate_message, parent):
        """ Initialize a Validator object.

        :type throw_exception: Throw a ValidateError exception
        :param field: Model.field | Column to listen
        :param interpolate_message: Validator interpolates message with
            values from context if True, outputs original message otherwise
        """
        self.parent = weakref.ref(parent)
        self.field = field
        self.allow_null = allow_null
        self.throw_exception = throw_exception
        self.message = message
        self.interpolate_message = interpolate_message
        self.__create_event() 
Example #6
Source File: mutable.py    From planespotter with MIT License 6 votes vote down vote up
def associate_with(cls, sqltype):
        """Associate this wrapper with all future mapped columns
        of the given type.

        This is a convenience method that calls
        ``associate_with_attribute`` automatically.

        .. warning::

           The listeners established by this method are *global*
           to all mappers, and are *not* garbage collected.   Only use
           :meth:`.associate_with` for types that are permanent to an
           application, not with ad-hoc types else this will cause unbounded
           growth in memory usage.

        """

        def listen_for_type(mapper, class_):
            for prop in mapper.column_attrs:
                if isinstance(prop.columns[0].type, sqltype):
                    cls.associate_with_attribute(getattr(class_, prop.key))

        event.listen(mapper, 'mapper_configured', listen_for_type) 
Example #7
Source File: events.py    From Fluid-Designer with GNU General Public License v3.0 6 votes vote down vote up
def _listen(cls, event_key, raw=False, propagate=False, **kw):
            target, identifier, fn = \
                event_key.dispatch_target, event_key.identifier, event_key.fn

            if target.class_ in target.all_holds:
                collection = target.all_holds[target.class_]
            else:
                collection = target.all_holds[target.class_] = {}

            event.registry._stored_in_collection(event_key, target)
            collection[event_key._key] = (event_key, raw, propagate)

            if propagate:
                stack = list(target.class_.__subclasses__())
                while stack:
                    subclass = stack.pop(0)
                    stack.extend(subclass.__subclasses__())
                    subject = target.resolve(subclass)
                    if subject is not None:
                        # we are already going through __subclasses__()
                        # so leave generic propagate flag False
                        event_key.with_dispatch_target(subject).\
                            listen(raw=raw, propagate=False, **kw) 
Example #8
Source File: events.py    From jbox with MIT License 6 votes vote down vote up
def _listen(cls, event_key, raw=False, propagate=False, **kw):
            target, identifier, fn = \
                event_key.dispatch_target, event_key.identifier, event_key.fn

            if target.class_ in target.all_holds:
                collection = target.all_holds[target.class_]
            else:
                collection = target.all_holds[target.class_] = {}

            event.registry._stored_in_collection(event_key, target)
            collection[event_key._key] = (event_key, raw, propagate)

            if propagate:
                stack = list(target.class_.__subclasses__())
                while stack:
                    subclass = stack.pop(0)
                    stack.extend(subclass.__subclasses__())
                    subject = target.resolve(subclass)
                    if subject is not None:
                        # we are already going through __subclasses__()
                        # so leave generic propagate flag False
                        event_key.with_dispatch_target(subject).\
                            listen(raw=raw, propagate=False, **kw) 
Example #9
Source File: test_reflection.py    From jbox with MIT License 6 votes vote down vote up
def define_views(cls, metadata, schema):
        for table_name in ('users', 'email_addresses'):
            fullname = table_name
            if schema:
                fullname = "%s.%s" % (schema, table_name)
            view_name = fullname + '_v'
            query = "CREATE VIEW %s AS SELECT * FROM %s" % (
                view_name, fullname)

            event.listen(
                metadata,
                "after_create",
                DDL(query)
            )
            event.listen(
                metadata,
                "before_drop",
                DDL("DROP VIEW %s" % view_name)
            ) 
Example #10
Source File: events.py    From Fluid-Designer with GNU General Public License v3.0 6 votes vote down vote up
def _listen(cls, event_key, propagate=True, **kw):
        target, identifier, fn = \
            event_key.dispatch_target, event_key.identifier, \
            event_key._listen_fn

        def listen(target_cls, *arg):
            listen_cls = target()
            if propagate and issubclass(target_cls, listen_cls):
                return fn(target_cls, *arg)
            elif not propagate and target_cls is listen_cls:
                return fn(target_cls, *arg)

        def remove(ref):
            key = event.registry._EventKey(
                None, identifier, listen,
                instrumentation._instrumentation_factory)
            getattr(instrumentation._instrumentation_factory.dispatch,
                    identifier).remove(key)

        target = weakref.ref(target.class_, remove)

        event_key.\
            with_dispatch_target(instrumentation._instrumentation_factory).\
            with_wrapper(listen).base_listen(**kw) 
Example #11
Source File: test_reflection.py    From Fluid-Designer with GNU General Public License v3.0 6 votes vote down vote up
def define_views(cls, metadata, schema):
        for table_name in ('users', 'email_addresses'):
            fullname = table_name
            if schema:
                fullname = "%s.%s" % (schema, table_name)
            view_name = fullname + '_v'
            query = "CREATE VIEW %s AS SELECT * FROM %s" % (
                view_name, fullname)

            event.listen(
                metadata,
                "after_create",
                DDL(query)
            )
            event.listen(
                metadata,
                "before_drop",
                DDL("DROP VIEW %s" % view_name)
            ) 
Example #12
Source File: events.py    From pyRevit with GNU General Public License v3.0 6 votes vote down vote up
def _listen(cls, event_key, propagate=True, **kw):
        target, identifier, fn = \
            event_key.dispatch_target, event_key.identifier, \
            event_key._listen_fn

        def listen(target_cls, *arg):
            listen_cls = target()
            if propagate and issubclass(target_cls, listen_cls):
                return fn(target_cls, *arg)
            elif not propagate and target_cls is listen_cls:
                return fn(target_cls, *arg)

        def remove(ref):
            key = event.registry._EventKey(
                None, identifier, listen,
                instrumentation._instrumentation_factory)
            getattr(instrumentation._instrumentation_factory.dispatch,
                    identifier).remove(key)

        target = weakref.ref(target.class_, remove)

        event_key.\
            with_dispatch_target(instrumentation._instrumentation_factory).\
            with_wrapper(listen).base_listen(**kw) 
Example #13
Source File: test_reflection.py    From pyRevit with GNU General Public License v3.0 6 votes vote down vote up
def define_views(cls, metadata, schema):
        for table_name in ('users', 'email_addresses'):
            fullname = table_name
            if schema:
                fullname = "%s.%s" % (schema, table_name)
            view_name = fullname + '_v'
            query = "CREATE VIEW %s AS SELECT * FROM %s" % (
                view_name, fullname)

            event.listen(
                metadata,
                "after_create",
                DDL(query)
            )
            event.listen(
                metadata,
                "before_drop",
                DDL("DROP VIEW %s" % view_name)
            ) 
Example #14
Source File: ddl.py    From pyRevit with GNU General Public License v3.0 5 votes vote down vote up
def execute_at(self, event_name, target):
        """Link execution of this DDL to the DDL lifecycle of a SchemaItem.

        Links this ``DDLElement`` to a ``Table`` or ``MetaData`` instance,
        executing it when that schema item is created or dropped. The DDL
        statement will be executed using the same Connection and transactional
        context as the Table create/drop itself. The ``.bind`` property of
        this statement is ignored.

        :param event:
          One of the events defined in the schema item's ``.ddl_events``;
          e.g. 'before-create', 'after-create', 'before-drop' or 'after-drop'

        :param target:
          The Table or MetaData instance for which this DDLElement will
          be associated with.

        A DDLElement instance can be linked to any number of schema items.

        ``execute_at`` builds on the ``append_ddl_listener`` interface of
        :class:`.MetaData` and :class:`.Table` objects.

        Caveat: Creating or dropping a Table in isolation will also trigger
        any DDL set to ``execute_at`` that Table's MetaData.  This may change
        in a future release.

        """

        def call_event(target, connection, **kw):
            if self._should_execute_deprecated(event_name,
                                               target, connection, **kw):
                return connection.execute(self.against(target))

        event.listen(target, "" + event_name.replace('-', '_'), call_event) 
Example #15
Source File: engine.py    From opentelemetry-python with Apache License 2.0 5 votes vote down vote up
def _wrap_create_engine(func, module, args, kwargs):
    """Trace the SQLAlchemy engine, creating an `EngineTracer`
    object that will listen to SQLAlchemy events.
    """
    engine = func(*args, **kwargs)
    EngineTracer(_get_tracer(engine), None, engine)
    return engine 
Example #16
Source File: api.py    From pyRevit with GNU General Public License v3.0 5 votes vote down vote up
def listens_for(target, identifier, *args, **kw):
    """Decorate a function as a listener for the given target + identifier.

    e.g.::

        from sqlalchemy import event
        from sqlalchemy.schema import UniqueConstraint

        @event.listens_for(UniqueConstraint, "after_parent_attach")
        def unique_constraint_name(const, table):
            const.name = "uq_%s_%s" % (
                table.name,
                list(const.columns)[0].name
            )

    A given function can also be invoked for only the first invocation
    of the event using the ``once`` argument::

        @event.listens_for(Mapper, "before_configure", once=True)
        def on_config():
            do_config()


    .. versionadded:: 0.9.4 Added ``once=True`` to :func:`.event.listen`
       and :func:`.event.listens_for`.

    .. seealso::

        :func:`.listen` - general description of event listening

    """
    def decorate(fn):
        listen(target, identifier, fn, *args, **kw)
        return fn
    return decorate 
Example #17
Source File: extensions.py    From flask-shop with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def __declare_last__(cls):
        event.listen(cls, "after_insert", cls._flush_insert_event)
        event.listen(cls, "before_update", cls._flush_before_update_event)
        event.listen(cls, "after_update", cls._flush_after_update_event)
        event.listen(cls, "after_delete", cls._flush_delete_event) 
Example #18
Source File: engine.py    From opentelemetry-python with Apache License 2.0 5 votes vote down vote up
def __init__(self, tracer, service, engine):
        self.tracer = tracer
        self.engine = engine
        self.vendor = _normalize_vendor(engine.name)
        self.service = service or self.vendor
        self.name = "%s.query" % self.vendor
        self.current_span = None

        listen(engine, "before_cursor_execute", self._before_cur_exec)
        listen(engine, "after_cursor_execute", self._after_cur_exec)
        listen(engine, "handle_error", self._handle_error)

    # pylint: disable=unused-argument 
Example #19
Source File: api.py    From pyRevit with GNU General Public License v3.0 5 votes vote down vote up
def contains(target, identifier, fn):
    """Return True if the given target/ident/fn is set up to listen.

    .. versionadded:: 0.9.0

    """

    return _event_key(target, identifier, fn).contains() 
Example #20
Source File: api.py    From planespotter with MIT License 5 votes vote down vote up
def contains(target, identifier, fn):
    """Return True if the given target/ident/fn is set up to listen.

    .. versionadded:: 0.9.0

    """

    return _event_key(target, identifier, fn).contains() 
Example #21
Source File: ddl.py    From Fluid-Designer with GNU General Public License v3.0 5 votes vote down vote up
def execute_at(self, event_name, target):
        """Link execution of this DDL to the DDL lifecycle of a SchemaItem.

        Links this ``DDLElement`` to a ``Table`` or ``MetaData`` instance,
        executing it when that schema item is created or dropped. The DDL
        statement will be executed using the same Connection and transactional
        context as the Table create/drop itself. The ``.bind`` property of
        this statement is ignored.

        :param event:
          One of the events defined in the schema item's ``.ddl_events``;
          e.g. 'before-create', 'after-create', 'before-drop' or 'after-drop'

        :param target:
          The Table or MetaData instance for which this DDLElement will
          be associated with.

        A DDLElement instance can be linked to any number of schema items.

        ``execute_at`` builds on the ``append_ddl_listener`` interface of
        :class:`.MetaData` and :class:`.Table` objects.

        Caveat: Creating or dropping a Table in isolation will also trigger
        any DDL set to ``execute_at`` that Table's MetaData.  This may change
        in a future release.

        """

        def call_event(target, connection, **kw):
            if self._should_execute_deprecated(event_name,
                                               target, connection, **kw):
                return connection.execute(self.against(target))

        event.listen(target, "" + event_name.replace('-', '_'), call_event) 
Example #22
Source File: api.py    From planespotter with MIT License 5 votes vote down vote up
def listens_for(target, identifier, *args, **kw):
    """Decorate a function as a listener for the given target + identifier.

    e.g.::

        from sqlalchemy import event
        from sqlalchemy.schema import UniqueConstraint

        @event.listens_for(UniqueConstraint, "after_parent_attach")
        def unique_constraint_name(const, table):
            const.name = "uq_%s_%s" % (
                table.name,
                list(const.columns)[0].name
            )

    A given function can also be invoked for only the first invocation
    of the event using the ``once`` argument::

        @event.listens_for(Mapper, "before_configure", once=True)
        def on_config():
            do_config()


    .. versionadded:: 0.9.4 Added ``once=True`` to :func:`.event.listen`
       and :func:`.event.listens_for`.

    .. seealso::

        :func:`.listen` - general description of event listening

    """
    def decorate(fn):
        listen(target, identifier, fn, *args, **kw)
        return fn
    return decorate 
Example #23
Source File: test_reflection.py    From Fluid-Designer with GNU General Public License v3.0 5 votes vote down vote up
def define_temp_tables(cls, metadata):
        # cheat a bit, we should fix this with some dialect-level
        # temp table fixture
        if testing.against("oracle"):
            kw = {
                'prefixes': ["GLOBAL TEMPORARY"],
                'oracle_on_commit': 'PRESERVE ROWS'
            }
        else:
            kw = {
                'prefixes': ["TEMPORARY"],
            }

        user_tmp = Table(
            "user_tmp", metadata,
            Column("id", sa.INT, primary_key=True),
            Column('name', sa.VARCHAR(50)),
            Column('foo', sa.INT),
            sa.UniqueConstraint('name', name='user_tmp_uq'),
            sa.Index("user_tmp_ix", "foo"),
            **kw
        )
        if testing.requires.view_reflection.enabled and \
                testing.requires.temporary_views.enabled:
            event.listen(
                user_tmp, "after_create",
                DDL("create temporary view user_tmp_v as "
                    "select * from user_tmp")
            )
            event.listen(
                user_tmp, "before_drop",
                DDL("drop view user_tmp_v")
            ) 
Example #24
Source File: events.py    From flask-unchained with MIT License 5 votes vote down vote up
def slugify(field_name, slug_field_name=None, mutable=False):
    """Class decorator to specify a field to slugify. Slugs are immutable by
    default unless mutable=True is passed.

    Usage::

        @slugify('title')
        def Post(Model):
            title = Column(String(100))
            slug = Column(String(100))

        # pass a second argument to specify the slug attribute field:
        @slugify('title', 'title_slug')
        def Post(Model)
            title = Column(String(100))
            title_slug = Column(String(100))

        # optionally set mutable to True for a slug that changes every time
        # the slugified field changes:
        @slugify('title', mutable=True)
        def Post(Model):
            title = Column(String(100))
            slug = Column(String(100))
    """
    slug_field_name = slug_field_name or 'slug'

    def _set_slug(target, value, old_value, _, mutable=False):
        existing_slug = getattr(target, slug_field_name)
        if existing_slug and not mutable:
            return
        if value and (not existing_slug or value != old_value):
            setattr(target, slug_field_name, _slugify(value))

    def wrapper(cls):
        event.listen(getattr(cls, field_name), 'set',
                     partial(_set_slug, mutable=mutable))
        return cls
    return wrapper 
Example #25
Source File: events.py    From flask-unchained with MIT License 5 votes vote down vote up
def on(*args, **listen_kwargs):
    """Class method decorator for SQLAlchemy models. Must be used in
    conjunction with the :func:`.attach_events` class decorator

    Usage::

        @attach_events
        class Post(Model):
            uuid = Column(String(36))
            post_tags = relationship('PostTag', back_populates='post')  # m2m

            # instance event (only one positional argument, the event name)
            # kwargs are passed on to the sqlalchemy.event.listen function
            @on('init', once=True)
            def generate_uuid(self, args, kwargs):
                self.uuid = str(uuid.uuid4())

            # attribute event (two positional args, field name and event name)
            @on('post_tags', 'append')
            def set_tag_order(self, post_tag, initiating_event):
                if not post_tag.order:
                    post_tag.order = len(self.post_tags) + 1
    """
    if len(args) == 1:
        field_name, event_name = (None, args[0])
    elif len(args) == 2:
        field_name, event_name = args
    else:
        raise NotImplementedError('@on accepts only one or two positional arguments')

    def wrapper(fn):
        setattr(fn, _SQLAlchemyEvent.ATTR,
                _SQLAlchemyEvent(field_name, event_name, listen_kwargs))
        return fn
    return wrapper 
Example #26
Source File: events.py    From flask-unchained with MIT License 5 votes vote down vote up
def attach_events(*args):
    """Class decorator for SQLAlchemy models to attach listeners for class
    methods decorated with :func:`.on`

    Usage::

        @attach_events
        class User(Model):
            email = Column(String(50))

            @on('email', 'set')
            def lowercase_email(self, new_value, old_value, initiating_event):
                self.email = new_value.lower()
    """
    def wrapper(cls):
        for name, fn in cls.__dict__.items():
            if not name.startswith('__') and hasattr(fn, _SQLAlchemyEvent.ATTR):
                e = getattr(fn, _SQLAlchemyEvent.ATTR)
                if e.field_name:
                    event.listen(getattr(cls, e.field_name), e.event_name, fn,
                                 **e.listen_kwargs)
                else:
                    event.listen(cls, e.event_name, fn, **e.listen_kwargs)
        return cls
    if args and callable(args[0]):
        return wrapper(args[0])
    return wrapper 
Example #27
Source File: base.py    From ctfscoreboard with Apache License 2.0 5 votes vote down vote up
def __enter__(self):
        event.listen(*self._sql_listen_args)
        return self 
Example #28
Source File: events.py    From Fluid-Designer with GNU General Public License v3.0 5 votes vote down vote up
def after_parent_attach(self, target, parent):
        """Called after a :class:`.SchemaItem` is associated with
        a parent :class:`.SchemaItem`.

        :param target: the target object
        :param parent: the parent to which the target is being attached.

        :func:`.event.listen` also accepts a modifier for this event:

        :param propagate=False: When True, the listener function will
         be established for any copies made of the target object,
         i.e. those copies that are generated when
         :meth:`.Table.tometadata` is used.

        """ 
Example #29
Source File: events.py    From Fluid-Designer with GNU General Public License v3.0 5 votes vote down vote up
def before_parent_attach(self, target, parent):
        """Called before a :class:`.SchemaItem` is associated with
        a parent :class:`.SchemaItem`.

        :param target: the target object
        :param parent: the parent to which the target is being attached.

        :func:`.event.listen` also accepts a modifier for this event:

        :param propagate=False: When True, the listener function will
         be established for any copies made of the target object,
         i.e. those copies that are generated when
         :meth:`.Table.tometadata` is used.

        """ 
Example #30
Source File: events.py    From Fluid-Designer with GNU General Public License v3.0 5 votes vote down vote up
def populate(cls, class_, subject):
        for subclass in class_.__mro__:
            if subclass in cls.all_holds:
                collection = cls.all_holds[subclass]
                for event_key, raw, propagate in collection.values():
                    if propagate or subclass is class_:
                        # since we can't be sure in what order different
                        # classes in a hierarchy are triggered with
                        # populate(), we rely upon _EventsHold for all event
                        # assignment, instead of using the generic propagate
                        # flag.
                        event_key.with_dispatch_target(subject).\
                            listen(raw=raw, propagate=False)