Example #1
0
 def direction(self):
     symbols = [part.property.direction for part in self.parts]
     if symbol('MANYTOMANY') in symbols:
         return symbol('MANYTOMANY')
     elif symbol('MANYTOONE') in symbols and symbol('ONETOMANY') in symbols:
         return symbol('MANYTOMANY')
     return symbols[0]
Example #2
0
 def direction(self):
     symbols = [part.property.direction for part in self.parts]
     if symbol('MANYTOMANY') in symbols:
         return symbol('MANYTOMANY')
     elif symbol('MANYTOONE') in symbols and symbol('ONETOMANY') in symbols:
         return symbol('MANYTOMANY')
     return symbols[0]
Example #3
0
    def _get_valid_field_names(self):
        inspect_mapper = inspect(self.model)
        columns = inspect_mapper.columns
        orm_descriptors = inspect_mapper.all_orm_descriptors

        column_names = columns.keys()
        hybrid_names = [
            key for key, item in orm_descriptors.items()
            if item.extension_type == symbol('HYBRID_PROPERTY')
            or item.extension_type == symbol('HYBRID_METHOD')
        ]

        return set(column_names) | set(hybrid_names)
Example #4
0
            def on_set_attr(target, value, old_value, initiator):
                if old_value is None or old_value in (symbol('NEVER_SET'), symbol('NO_VALUE')):
                    return

                store_manager = StoreManager.get_current_store_manager()
                if store_manager.delete_orphan:
                    if value is not old_value:
                        if collection:
                            if isinstance(old_value, dict):
                                store_manager.orphaned(*(set(old_value.values()) - set(value.values())))
                            else:
                                store_manager.orphaned(*(set(old_value) - set(value)))
                        else:
                            store_manager.orphaned(old_value)
Example #5
0
def create_offer_event_on_payout_changed(target, value, old_value, initiator):
    if old_value != symbol('NO_VALUE'):
        if value != old_value:
            offer_event = models.OfferEvent()
            event_type = models.OfferEvent.TYPE_PAYOUT_UP if value > old_value else models.OfferEvent.TYPE_PAYOUT_DOWN
            offer_event.name = event_type
            offer_event.offer = target
            db.session.add(offer_event)
            db.session.flush()
Example #6
0
def before_flush(session, *args):
    from intranet3.models import Client
    project_or_client = None
    for obj in session:
        if isinstance(obj, (Project, Client)) and hasattr(obj, 'old_coordinator'):
            project_or_client = obj

    if not project_or_client:
        return

    oldc = project_or_client.old_coordinator
    if oldc and oldc != symbol('NO_VALUE'):
        remove_coordinator(session, project_or_client.old_coordinator)

    if project_or_client.coordinator_id:
        add_coordinator(session, project_or_client.coordinator_id)
Example #7
0
def before_flush(session, *args):
    from intranet3.models import Client
    project_or_client = None
    for obj in session:
        if isinstance(obj, (Project, Client)) and hasattr(obj, 'old_coordinator'):
            project_or_client = obj

    if not project_or_client:
        return

    oldc = project_or_client.old_coordinator
    if oldc and oldc != symbol('NO_VALUE'):
        remove_coordinator(session, project_or_client.old_coordinator)

    if project_or_client.coordinator_id:
        add_coordinator(session, project_or_client.coordinator_id)
Example #8
0
def db_attr_event(target, value, oldvalue, initiator):
    """
    Find the appropriate object and verify.
    Dispatch if necessary.
    """
    op = 'new' if oldvalue == symbol('NO_VALUE') else 'dirty'

    reg_key = 'database:%s:%s:%s' % (target.__tablename__, initiator.key, op)
    _pv_semaphore.acquire()    
    actions = event_registry.get(reg_key, None)
    _pv_semaphore.release()    
    kwargs = {'newvalue': value, 'oldvalue': oldvalue}
    if actions:
        for action in actions:
            if action.verify(target, op, **kwargs):
                action.dispatch(target, op, **kwargs)

    return target
            def create(target, value, oldvalue, initiator):
                if any(
                    [
                        oldvalue is symbol("NO_VALUE"),
                        value == oldvalue,
                    ]
                ):
                    return value

                db.session.add(
                    cls(
                        table=target.__tablename__,
                        row=target.id,
                        field=initiator.key,
                        old_value=_convert(oldvalue),
                        new_value=_convert(value),
                    )
                )
                return value
Example #10
0
def last_fixture(model):
    """
    Return the last created and non-deleted fixture for given model. If no
    non-deleted record was found this function returns None.

    :param model: sqlalchemy declarative model
    """
    while FixtureRegistry.records[model]:
        # fetch the last inserted record
        record = FixtureRegistry.records[model][-1]
        state = record._sa_instance_state
        detached = False
        # if we find expired attributes, force load them all
        if state.expired_attributes:
            try:
                state(None, symbol('PASSIVE_OFF'))
            except DetachedInstanceError:
                detached = True
            except ObjectDeletedError:
                state.deleted = True
        if detached or state.deleted or not object_session(record):
            FixtureRegistry.records[model].pop()
        else:
            return record
Example #11
0
def last_fixture(model):
    """
    Return the last created and non-deleted fixture for given model. If no
    non-deleted record was found this function returns None.

    :param model: sqlalchemy declarative model
    """
    while FixtureRegistry.records[model]:
        # fetch the last inserted record
        record = FixtureRegistry.records[model][-1]
        state = record._sa_instance_state
        detached = False
        # if we find expired attributes, force load them all
        if state.expired_attributes:
            try:
                state(None, symbol('PASSIVE_OFF'))
            except DetachedInstanceError:
                detached = True
            except ObjectDeletedError:
                state.deleted = True
        if detached or state.deleted or not object_session(record):
            FixtureRegistry.records[model].pop()
        else:
            return record
Example #12
0
            __tablename__ = 'somemodel'
            id = sa.Column(sa.Integer, primary_key=True)
    """

    created = sa.Column(sa.DateTime, default=datetime.utcnow, nullable=False)
    updated = sa.Column(sa.DateTime, default=datetime.utcnow, nullable=False)


@sa.event.listens_for(Timestamp, 'before_update', propagate=True)
def timestamp_before_update(mapper, connection, target):
    # When a model with a timestamp is updated; force update the updated
    # timestamp.
    target.updated = datetime.utcnow()


NO_VALUE = symbol('NO_VALUE')
NOT_LOADED_REPR = '<not loaded>'


def _generic_repr_method(self, fields):
    state = sa.inspect(self)
    field_reprs = []
    if not fields:
        fields = state.mapper.columns.keys()
    for key in fields:
        value = state.attrs[key].loaded_value
        if value == NO_VALUE:
            value = NOT_LOADED_REPR
        else:
            value = repr(value)
        field_reprs.append('='.join((key, value)))
Example #13
0
 def test_direction(self, SubSection):
     assert (AttrPath(SubSection,
                      'section').direction == symbol('MANYTOONE'))
Example #14
0
 def test_direction(self, SubSection):
     assert (
         AttrPath(SubSection, 'section').direction == symbol('MANYTOONE')
     )
Example #15
0
"""

from abc import ABCMeta
import typing as t

import sqlalchemy as sa
from sqlalchemy import MetaData, orm
from sqlalchemy.orm import DeclarativeMeta, declarative_base as _declarative_base
from sqlalchemy.sql import Delete, Insert, Select, Update
from sqlalchemy.util.langhelpers import symbol

from . import event
from .utils import is_iterable_but_not_string


NO_VALUE = symbol("NO_VALUE")


class DeclarativeModel(metaclass=ABCMeta):
    @classmethod
    def __subclasshook__(cls, class_):
        if cls is DeclarativeModel:
            return isinstance(class_, DeclarativeMeta)
        return NotImplemented  # pragma: no cover


class ModelMeta(DeclarativeMeta):
    """Model metaclass that prepares model classes for event registration hooks."""

    def __new__(mcs, name, bases, dct):
        cls = DeclarativeMeta.__new__(mcs, name, bases, dct)
Example #16
0
class TestAttrPath(TestCase):
    def create_models(self):
        class Document(self.Base):
            __tablename__ = 'document'
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.Unicode(255))
            locale = sa.Column(sa.String(10))

        class Section(self.Base):
            __tablename__ = 'section'
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.Unicode(255))
            locale = sa.Column(sa.String(10))

            document_id = sa.Column(sa.Integer, sa.ForeignKey(Document.id))

            document = sa.orm.relationship(Document, backref='sections')

        class SubSection(self.Base):
            __tablename__ = 'subsection'
            id = sa.Column(sa.Integer, primary_key=True)
            name = sa.Column(sa.Unicode(255))
            locale = sa.Column(sa.String(10))

            section_id = sa.Column(sa.Integer, sa.ForeignKey(Section.id))

            section = sa.orm.relationship(Section, backref='subsections')

        self.Document = Document
        self.Section = Section
        self.SubSection = SubSection

    @mark.parametrize(('class_', 'path', 'direction'),
                      (('SubSection', 'section', symbol('MANYTOONE')), ))
    def test_direction(self, class_, path, direction):
        assert (AttrPath(getattr(self, class_), path).direction == direction)

    def test_invert(self):
        path = ~AttrPath(self.SubSection, 'section.document')
        assert path.parts == [self.Document.sections, self.Section.subsections]
        assert str(path.path) == 'sections.subsections'

    def test_len(self):
        len(AttrPath(self.SubSection, 'section.document')) == 2

    def test_init(self):
        path = AttrPath(self.SubSection, 'section.document')
        assert path.class_ == self.SubSection
        assert path.path == Path('section.document')

    def test_iter(self):
        path = AttrPath(self.SubSection, 'section.document')
        assert list(path) == [self.SubSection.section, self.Section.document]

    def test_repr(self):
        path = AttrPath(self.SubSection, 'section.document')
        assert repr(path) == ("AttrPath(SubSection, 'section.document')")

    def test_index(self):
        path = AttrPath(self.SubSection, 'section.document')
        assert path.index(self.Section.document) == 1
        assert path.index(self.SubSection.section) == 0

    def test_getitem(self):
        path = AttrPath(self.SubSection, 'section.document')
        assert path[0] is self.SubSection.section
        assert path[1] is self.Section.document

    def test_getitem_with_slice(self):
        path = AttrPath(self.SubSection, 'section.document')
        assert path[:] == AttrPath(self.SubSection, 'section.document')
        assert path[:-1] == AttrPath(self.SubSection, 'section')
        assert path[1:] == AttrPath(self.Section, 'document')

    def test_eq(self):
        assert (AttrPath(self.SubSection, 'section.document') == AttrPath(
            self.SubSection, 'section.document'))
        assert not (AttrPath(self.SubSection, 'section') == AttrPath(
            self.SubSection, 'section.document'))

    def test_ne(self):
        assert not (AttrPath(self.SubSection, 'section.document') != AttrPath(
            self.SubSection, 'section.document'))
        assert (AttrPath(self.SubSection, 'section') != AttrPath(
            self.SubSection, 'section.document'))
Example #17
0
def before_flush(session, *args):
    """ Set 'parent_url' and update it when 'url_part' was changed.
    """

    nones = (symbol('NO_VALUE'), symbol('NEVER_SET'), None)

    # NOTE: cannot know objects order in session.new and session.dirty,
    #       for that reason multiple 'for' cicles are needed.

    # Handle 'CommonInfo.parent_url' for 'new' objects.
    for obj in session.new:

        if not isinstance(obj, CommonInfo):
            continue

        if obj.node is None and obj.node_id is None:
            msg = '{} object must belong to a Node.'
            msg = msg.format(obj.__class__.__name__)
            raise ValueError(msg)

        elif obj.node is None:
            obj.node = Node.get(session, obj.node_id)

        #log.info("Update 'parent_url' of %s", obj.label)
        obj.update_parent_url()

    # Handle 'PageInfo.content' for 'new' objects.
    for obj in session.new:

        if not isinstance(obj, PageInfo):
            continue

        #log.info("Update associations of %s", obj.label)
        obj.update_associations()

    # Handle 'PageInfo.content' for 'new' objects.
    for obj in session.dirty:

        if not isinstance(obj, PageInfo) or \
           not hasattr(obj, '_attrs_updates') or \
           'content' not in obj._attrs_updates:
            continue

        #log.info("Update associations of %s", obj.label)
        obj.update_associations()

    # First phase.
    # Handle 'node' changes in CommonInfo objects:
    # replace olds CommonInfo.parent_url with new ones.
    for obj in session.dirty:

        if not isinstance(obj, CommonInfo) or \
           not hasattr(obj, '_attrs_updates') or \
           'node' not in obj._attrs_updates:
            continue

        #log.info("Update parent_url of %s", obj.label)
        obj.update_parent_url()

    # Second phase: handle Page|Section objects changes.
    # Handle 'parent_id' changes in Page and Section objects:
    # replace olds CommonInfo.parent_url with new ones.
    for obj in session.dirty:

        if not isinstance(obj, (Page, Section)) or \
           not hasattr(obj, '_attrs_updates') or \
           'parent_id' not in obj._attrs_updates:
            continue

        #log.debug('Update translations of %s', obj.id)

        for translation in obj.translations:
            #log.info('Update translation: %s', translation.label)
            translation.update_parent_url()

    # Third phase: handle CommonInfo.url_part changes.
    # Handle 'url_part' changes in CommonInfo objects:
    # replace olds CommonInfo.parent_url with new ones.
    for obj in session.dirty:

        if not isinstance(obj, CommonInfo) or \
           not hasattr(obj, '_attrs_updates') or \
           'url_part' not in obj._attrs_updates:
            continue

        old = obj._attrs_updates['url_part']['old']
        new = obj._attrs_updates['url_part']['new']

        if old in nones or old == new:
            continue

        #log.info("Update children of %s", obj.label)
        obj.update_children_parent_url()
import pdb
from conf import config 

from sqlalchemy import event
from sqlalchemy.orm import mapper
from sqlalchemy.util.langhelpers import symbol

from sqlalchemy.sql.expression import Select
NO_VALUE = symbol("NO_VALUE")

from lib.db_connection import db_session

try:
    from celery.task import task as ctask
    CELERY_INSTALLED = True
except ImportError, e:
    print "You don't have celery installed, running in syncronous mode"
    def ctask(actual_func, *args, **kwargs):
        return actual_func
    CELERY_INSTALLED = False


class deferred(object):
    def __init__(self, trigger_condition,
                 change_field=False,  
                 before_predicate=lambda obj: True,
                 run_predicate=lambda obj: True):
        """The arguments to init are the arguments that are available
        to the @deferred decorator
        """
        self.before_predicate = before_predicate