Esempio n. 1
0
    def _modify_params_for_relationships(self, entity, params, delete_first=True):
        entity = resolve_entity(entity)
        mapper = class_mapper(entity)
        relations = self.get_relations(entity)

        for relation in relations:
            if relation in params:
                prop = mapper.get_property(relation)
                target = prop.argument
                target = resolve_entity(target)
                value = params[relation]
                if value:
                    if prop.uselist and isinstance(value, list):
                        target_obj = []
                        for v in value:
                            try:
                                object_mapper(v)
                                target_obj.append(v)
                            except UnmappedInstanceError:
                                if hasattr(target, 'primary_key'):
                                    pk = target.primary_key
                                else:
                                    pk = class_mapper(target).primary_key
                                if isinstance(v, string_type) and "/" in v:
                                    v = map(self._adapt_type, v.split("/"), pk)
                                    v = tuple(v)
                                else:
                                    v = self._adapt_type(v, pk[0])
                                #only add those items that come back
                                new_v = self.session.query(target).get(v)
                                if new_v is not None:
                                    target_obj.append(new_v)
                    elif prop.uselist:
                        try:
                            object_mapper(value)
                            target_obj = [value]
                        except UnmappedInstanceError:
                            mapper = target
                            if not isinstance(target, Mapper):
                                mapper = class_mapper(target)
                            if isinstance(mapper.primary_key[0].type, Integer):
                                value = int(value)
                            target_obj = [self.session.query(target).get(value)]
                    else:
                        try:
                            object_mapper(value)
                            target_obj = value
                        except UnmappedInstanceError:
                            if isinstance(value, string_type) and "/" in value:
                                value = map(self._adapt_type, value.split("/"), prop.remote_side)
                                value = tuple(value)
                            else:
                                value = self._adapt_type(value, list(prop.remote_side)[0])
                            target_obj = self.session.query(target).get(value)
                    params[relation] = target_obj
                else:
                    del params[relation]
        return params
Esempio n. 2
0
    def _get_related_class(self, entity, relation):
        entity = resolve_entity(entity)
        mapper = class_mapper(entity)
        prop = mapper.get_property(relation)

        target = resolve_entity(prop.argument)
        if not hasattr(target, 'class_'):
            target = class_mapper(target)

        return target.class_
Esempio n. 3
0
 def _modify_params_for_dates(self, entity, params):
     entity = resolve_entity(entity)
     mapper = class_mapper(entity)
     for key, value in list(params.items()):
         if key in mapper.c and value is not None:
             field = mapper.c[key]
             if hasattr(field, 'type'):
                 if isinstance(field.type, DateTime):
                     if not isinstance(value, datetime):
                         dt = datetime.strptime(value[:19], '%Y-%m-%d %H:%M:%S')
                         params[key] = dt
                 elif isinstance(field.type, Date):
                     if not isinstance(value, date):
                         dt = datetime.strptime(value, '%Y-%m-%d').date()
                         params[key] = dt
                 elif isinstance(field.type, Interval):
                     if not isinstance(value, timedelta):
                         d = re.match(
                             r'((?P<days>\d+) days, )?(?P<hours>\d+):'
                             r'(?P<minutes>\d+):(?P<seconds>\d+)',
                             str(value)).groupdict(0)
                         dt = timedelta(**dict(( (key, int(value))
                                                 for key, value in list(d.items()) )))
                         params[key] = dt
     return params
Esempio n. 4
0
    def get_dropdown_options(self, entity, field_name, view_names=None):
        if view_names is None:
            view_names = ['_name', 'name', 'description', 'title']
        if self.session is None:
            warn('No dropdown options will be shown for %s.  '
                 'Try passing the session into the initialization '
                 'of your form base object so that this sprocket '
                 'can have values in the drop downs'%entity)
            return []

        field = self.get_field(entity, field_name)

        target_field = entity
        if isinstance(field, PropertyLoader):
            target_field = field.argument
        target_field = resolve_entity(target_field)

        #some kind of relation
        if isinstance(target_field, Mapper):
            target_field = target_field.class_

        pk_fields = self.get_primary_fields(target_field)

        view_name = self.get_view_field_name(target_field, view_names)

        rows = self.session.query(target_field).all()

        if len(pk_fields) == 1:
            def build_pk(row):
                return getattr(row, pk_fields[0])
        else:
            def build_pk(row):
                return "/".join([str(getattr(row, pk)) for pk in pk_fields])

        return [ (build_pk(row), getattr(row, view_name)) for row in rows ]
Esempio n. 5
0
 def is_unique(self, entity, field_name, value):
     entity = resolve_entity(entity)
     field = getattr(entity, field_name)
     try:
         self.session.query(entity).filter(field==value).one()
     except NoResultFound:
         return True
     return False
Esempio n. 6
0
 def get_field(self, entity, name):
     entity = resolve_entity(entity)
     mapper = class_mapper(entity)
     try:
         return getattr(mapper.c, name)
     except (InvalidRequestError, AttributeError):
         try:
             return mapper.get_property(name)
         except InvalidRequestError:
             raise AttributeError
Esempio n. 7
0
    def is_relation(self, entity, field_name):
        entity = resolve_entity(entity)
        mapper = class_mapper(entity)

        try:
            property = mapper.get_property(field_name)
        except InvalidRequestError:
            return False

        if isinstance(property, PropertyLoader):
            return True
Esempio n. 8
0
    def is_relation(self, entity, field_name):
        entity = resolve_entity(entity)
        mapper = class_mapper(entity)

        try:
            property = mapper.get_property(field_name)
        except InvalidRequestError:
            return False

        if isinstance(property, PropertyLoader):
            return True
Esempio n. 9
0
    def get_fields(self, entity):
        entity = resolve_entity(entity)
        mapper = class_mapper(entity)
        field_names = list(mapper.c.keys())
        for prop in mapper.iterate_properties:
            try:
                mapper.c[prop.key]
                field_names.append(prop.key)
            except KeyError:
                mapper.get_property(prop.key)
                field_names.append(prop.key)

        return field_names
Esempio n. 10
0
    def get_fields(self, entity):
        entity = resolve_entity(entity)
        mapper = class_mapper(entity)
        field_names = list(mapper.c.keys())
        for prop in mapper.iterate_properties:
            try:
                getattr(mapper.c, prop.key)
                field_names.append(prop.key)
            except AttributeError:
                mapper.get_property(prop.key)
                field_names.append(prop.key)

        return field_names
Esempio n. 11
0
    def get_primary_fields(self, entity):
        entity = resolve_entity(entity)
        mapper = class_mapper(entity)
        fields = []

        for field_name in self.get_fields(entity):
            try:
                value = mapper.c[field_name]
            except KeyError:
                # Relations won't be attributes, but can't be primary anyway.
                continue
            if value.primary_key and not field_name in fields:
                fields.append(field_name)
        return fields
Esempio n. 12
0
    def get_primary_fields(self, entity):
        entity = resolve_entity(entity)
        mapper = class_mapper(entity)
        fields = []

        for field_name in self.get_fields(entity):
            try:
                value = getattr(mapper.c, field_name)
            except AttributeError:
                # Relations won't be attributes, but can't be primary anyway.
                continue
            if value.primary_key and not field_name in fields:
                fields.append(field_name)
        return fields
Esempio n. 13
0
    def query(self, entity, limit=None, offset=None, limit_fields=None,
            order_by=None, desc=False, field_names=[], filters={},
            substring_filters=[], **kw):
        entity = resolve_entity(entity)
        query = self.session.query(entity)

        filters = self._modify_params_for_dates(entity, filters)
        filters = self._modify_params_for_relationships(entity, filters)

        for field_name, value in filters.items():
            field = getattr(entity, field_name)
            if self.is_relation(entity, field_name) and isinstance(value, list):
                value = value[0]
                query = query.filter(field.contains(value))
            elif field_name in substring_filters and self.is_string(entity, field_name):
                escaped_value = re.sub('[\\\\%\\[\\]_]', '\\\\\g<0>', value.lower())
                query = query.filter(func.lower(field).contains(escaped_value, escape='\\'))
            else:
                query = query.filter(field==value) 

        count = query.count()

        if order_by is not None:
            if self.is_relation(entity, order_by):
                mapper = class_mapper(entity)
                class_ = None
                for prop in mapper.iterate_properties:
                    try:
                        class_ = prop.mapper.class_
                    except (AttributeError, KeyError):
                        pass
                query = self.session.query(entity).join(order_by)
                f = self.get_view_field_name(class_, field_names)
                field = self.get_field(class_, f)
            else:
                field = self.get_field(entity, order_by)

            if desc:
                field = _desc(field)
            query = query.order_by(field)

        if offset is not None:
            query = query.offset(offset)
        if limit is not None:
            query = query.limit(limit)

        objs = query.all()

        return count, objs
Esempio n. 14
0
    def create(self, entity, params):
        entity = resolve_entity(entity)
        params = self._modify_params_for_dates(entity, params)
        params = self._modify_params_for_relationships(entity, params)
        obj = entity()

        relations = self.get_relations(entity)
        mapper = class_mapper(entity)
        for key, value in params.items():
            if value is not None:
                if isinstance(value, FieldStorage):
                    value = value.file.read()
                try:
                    if key not in relations and value and isinstance(mapper.columns[key].type, Integer):
                        value = int(value)
                except KeyError:
                    pass
                setattr(obj, key, value)

        self.session.add(obj)
        self.session.flush()
        return obj
Esempio n. 15
0
    def get_dropdown_options(self, entity, field_name, view_names=None):
        if view_names is None:
            view_names = self.default_view_names

        if self.session is None:
            warn('No dropdown options will be shown for %s.  '
                 'Try passing the session into the initialization '
                 'of your form base object so that this sprocket '
                 'can have values in the drop downs' % entity)
            return []

        field = self.get_field(entity, field_name)

        target_field = entity
        if isinstance(field, PropertyLoader):
            target_field = field.argument
        target_field = resolve_entity(target_field)

        #some kind of relation
        if isinstance(target_field, Mapper):
            target_field = target_field.class_

        pk_fields = self.get_primary_fields(target_field)

        view_name = self.get_view_field_name(target_field, view_names)

        rows = self.session.query(target_field).all()

        if len(pk_fields) == 1:

            def build_pk(row):
                return getattr(row, pk_fields[0])
        else:

            def build_pk(row):
                return "/".join([str(getattr(row, pk)) for pk in pk_fields])

        return [(build_pk(row), getattr(row, view_name)) for row in rows]
Esempio n. 16
0
    def create(self, entity, params):
        entity = resolve_entity(entity)
        params = self._modify_params_for_dates(entity, params)
        params = self._modify_params_for_relationships(entity, params)
        obj = entity()

        relations = self.get_relations(entity)
        mapper = class_mapper(entity)
        for key, value in params.items():
            if value is not None:
                if isinstance(value, FieldStorage):
                    value = value.file.read()
                try:
                    if key not in relations and value and isinstance(
                            mapper.columns[key].type, Integer):
                        value = int(value)
                except KeyError:
                    pass
                setattr(obj, key, value)

        self.session.add(obj)
        self.session.flush()
        return obj
Esempio n. 17
0
 def _find_title_column(self, entity):
     entity = resolve_entity(entity)
     for column in class_mapper(entity).columns:
         if 'title' in column.info and column.info['title']:
             return column.key
     return None
Esempio n. 18
0
 def get_synonyms(self, entity):
     entity = resolve_entity(entity)
     mapper = class_mapper(entity)
     return [prop.key for prop in mapper.iterate_properties if isinstance(prop, SynonymProperty)]
Esempio n. 19
0
 def _relates_many(self, entity, field_name):
     entity = resolve_entity(entity)
     mapper = class_mapper(entity)
     property = mapper.get_property(field_name)
     return property.uselist
Esempio n. 20
0
    def _modify_params_for_relationships(self, entity, params):
        entity = resolve_entity(entity)
        mapper = class_mapper(entity)
        relations = self.get_relations(entity)

        for relation in relations:
            if relation in params:
                prop = mapper.get_property(relation)
                target = prop.argument
                target = resolve_entity(target)
                value = params[relation]
                if value:
                    if prop.uselist and isinstance(value, list):
                        target_obj = []
                        for v in value:
                            try:
                                object_mapper(v)
                                target_obj.append(v)
                            except UnmappedInstanceError:
                                if hasattr(target, 'primary_key'):
                                    pk = target.primary_key
                                else:
                                    pk = class_mapper(target).primary_key
                                if isinstance(v, string_type) and "/" in v:
                                    v = map(self._adapt_type, v.split("/"), pk)
                                    v = tuple(v)
                                else:
                                    v = self._adapt_type(v, pk[0])
                                #only add those items that come back
                                new_v = self.session.query(target).get(v)
                                if new_v is not None:
                                    target_obj.append(new_v)
                    elif prop.uselist:
                        try:
                            object_mapper(value)
                            target_obj = [value]
                        except UnmappedInstanceError:
                            mapper = target
                            if not isinstance(target, Mapper):
                                mapper = class_mapper(target)
                            value = self._adapt_type(value,
                                                     mapper.primary_key[0])
                            target_obj = [
                                self.session.query(target).get(value)
                            ]
                    else:
                        try:
                            object_mapper(value)
                            target_obj = value
                        except UnmappedInstanceError:
                            if isinstance(value, string_type) and "/" in value:
                                value = map(self._adapt_type, value.split("/"),
                                            prop.remote_side)
                                value = tuple(value)
                            else:
                                value = self._adapt_type(
                                    value,
                                    list(prop.remote_side)[0])
                            target_obj = self.session.query(target).get(value)
                    params[relation] = target_obj
                else:
                    if prop.uselist:
                        params[relation] = []
                    else:
                        params[relation] = None

        return params
Esempio n. 21
0
 def get_relations(self, entity):
     entity = resolve_entity(entity)
     mapper = class_mapper(entity)
     return [prop.key for prop in mapper.iterate_properties if isinstance(prop, PropertyLoader)]
Esempio n. 22
0
 def _find_title_column(self, entity):
     entity = resolve_entity(entity)
     for column in class_mapper(entity).columns:
         if 'title' in column.info and column.info['title']:
             return column.key
     return None
Esempio n. 23
0
    def query(self,
              entity,
              limit=None,
              offset=None,
              limit_fields=None,
              order_by=None,
              desc=False,
              filters={},
              substring_filters=[],
              search_related=False,
              related_field_names=None,
              **kw):
        entity = resolve_entity(entity)
        query = self.session.query(entity)

        filters = self._modify_params_for_dates(entity, filters)

        if search_related:
            # Values for related fields contain the text to search
            filters = self._modify_params_for_related_searches(
                entity,
                filters,
                view_names=related_field_names,
                substrings=substring_filters)
        else:
            # Values for related fields contain the primary key
            filters = self._modify_params_for_relationships(entity, filters)

        for field_name, value in filters.items():
            field = getattr(entity, field_name)
            if self.is_relation(entity, field_name) and isinstance(
                    value, list):
                related_class = self._get_related_class(entity, field_name)
                related_pk = self.get_primary_field(related_class)
                related_pk_col = getattr(related_class, related_pk)
                related_pk_values = (getattr(v, related_pk) for v in value)
                if self._relates_many(entity, field_name):
                    field_filter = field.any(
                        related_pk_col.in_(related_pk_values))
                else:
                    field_filter = field.has(
                        related_pk_col.in_(related_pk_values))
                query = query.filter(field_filter)
            elif field_name in substring_filters and self.is_string(
                    entity, field_name):
                escaped_value = self._escape_like(value.lower())
                query = query.filter(
                    func.lower(field).contains(escaped_value, escape='*'))
            else:
                query = query.filter(field == value)

        count = query.count()

        if order_by is not None:
            if not isinstance(order_by, (tuple, list)):
                order_by = [order_by]

            if not isinstance(desc, (tuple, list)):
                desc = [desc]

            for sort_by, sort_descending in zip_longest(order_by, desc):
                if self.is_relation(entity, sort_by):
                    mapper = class_mapper(entity)
                    class_ = self._get_related_class(entity, sort_by)
                    query = query.outerjoin(sort_by)
                    f = self.get_view_field_name(class_, related_field_names)
                    field = self.get_field(class_, f)
                else:
                    field = self.get_field(entity, sort_by)

                if sort_descending:
                    field = _desc(field)
                query = query.order_by(field)

        if offset is not None:
            query = query.offset(offset)
        if limit is not None:
            query = query.limit(limit)

        objs = query.all()

        return count, objs
Esempio n. 24
0
 def _get_obj(self, entity, pkdict):
     entity = resolve_entity(entity)
     pk_names = self.get_primary_fields(entity)
     pks = tuple([pkdict[n] for n in pk_names])
     return self.session.query(entity).get(pks)
Esempio n. 25
0
 def _get_obj(self, entity, pkdict):
     entity = resolve_entity(entity)
     pk_names = self.get_primary_fields(entity)
     pks = tuple([pkdict[n] for n in pk_names])
     return self.session.query(entity).get(pks)
Esempio n. 26
0
 def _relates_many(self, entity, field_name):
     entity = resolve_entity(entity)
     mapper = class_mapper(entity)
     property = mapper.get_property(field_name)
     return property.uselist
Esempio n. 27
0
    def query(self, entity, limit=None, offset=None, limit_fields=None,
              order_by=None, desc=False, filters={},
              substring_filters=[], search_related=False, related_field_names=None,
              **kw):
        entity = resolve_entity(entity)
        query = self.session.query(entity)

        filters = self._modify_params_for_dates(entity, filters)

        if search_related:
            # Values for related fields contain the text to search
            filters = self._modify_params_for_related_searches(entity, filters,
                                                               view_names=related_field_names,
                                                               substrings=substring_filters)
        else:
            # Values for related fields contain the primary key
            filters = self._modify_params_for_relationships(entity, filters)

        for field_name, value in filters.items():
            field = getattr(entity, field_name)
            if self.is_relation(entity, field_name) and isinstance(value, list):
                related_class = self._get_related_class(entity, field_name)
                related_pk = self.get_primary_field(related_class)
                related_pk_col = getattr(related_class, related_pk)
                related_pk_values = (getattr(v, related_pk) for v in value)
                if self._relates_many(entity, field_name):
                    field_filter = field.any(related_pk_col.in_(related_pk_values))
                else:
                    field_filter = field.has(related_pk_col.in_(related_pk_values))
                query = query.filter(field_filter)
            elif field_name in substring_filters and self.is_string(entity, field_name):
                escaped_value = self._escape_like(value.lower())
                query = query.filter(func.lower(field).contains(escaped_value, escape='*'))
            else:
                query = query.filter(field==value)

        count = query.count()

        if order_by is not None:
            if not isinstance(order_by, (tuple, list)):
                order_by = [order_by]

            if not isinstance(desc, (tuple, list)):
                desc = [desc]

            for sort_by, sort_descending in zip_longest(order_by, desc):
                if self.is_relation(entity, sort_by):
                    mapper = class_mapper(entity)
                    class_ = self._get_related_class(entity, sort_by)
                    query = query.outerjoin(sort_by)
                    f = self.get_view_field_name(class_, related_field_names)
                    field = self.get_field(class_, f)
                else:
                    field = self.get_field(entity, sort_by)

                if sort_descending:
                    field = _desc(field)
                query = query.order_by(field)

        if offset is not None:
            query = query.offset(offset)
        if limit is not None:
            query = query.limit(limit)

        objs = query.all()

        return count, objs
Esempio n. 28
0
    def query(self,
              entity,
              limit=None,
              offset=None,
              limit_fields=None,
              order_by=None,
              desc=False,
              field_names=[],
              filters={},
              substring_filters=[],
              **kw):
        entity = resolve_entity(entity)
        query = self.session.query(entity)

        filters = self._modify_params_for_dates(entity, filters)
        filters = self._modify_params_for_relationships(entity, filters)

        for field_name, value in filters.items():
            field = getattr(entity, field_name)
            if self.is_relation(entity, field_name) and isinstance(
                    value, list):
                value = value[0]
                query = query.filter(field.contains(value))
            elif field_name in substring_filters and self.is_string(
                    entity, field_name):
                escaped_value = re.sub('[\\\\%\\[\\]_]', '\\\\\g<0>',
                                       value.lower())
                query = query.filter(
                    func.lower(field).contains(escaped_value, escape='\\'))
            else:
                query = query.filter(field == value)

        count = query.count()

        if order_by is not None:
            if self.is_relation(entity, order_by):
                mapper = class_mapper(entity)
                class_ = None
                for prop in mapper.iterate_properties:
                    try:
                        class_ = prop.mapper.class_
                    except (AttributeError, KeyError):
                        pass
                query = self.session.query(entity).join(order_by)
                f = self.get_view_field_name(class_, field_names)
                field = self.get_field(class_, f)
            else:
                field = self.get_field(entity, order_by)

            if desc:
                field = _desc(field)
            query = query.order_by(field)

        if offset is not None:
            query = query.offset(offset)
        if limit is not None:
            query = query.limit(limit)

        objs = query.all()

        return count, objs