class GroupExtra(vdm.sqlalchemy.RevisionedObjectMixin, vdm.sqlalchemy.StatefulObjectMixin, domain_object.DomainObject): pass meta.mapper( GroupExtra, group_extra_table, properties={ 'group': orm.relation( group.Group, backref=orm.backref( '_extras', collection_class=orm.collections.attribute_mapped_collection( u'key'), cascade='all, delete, delete-orphan', ), ) }, order_by=[group_extra_table.c.group_id, group_extra_table.c.key], extension=[ vdm.sqlalchemy.Revisioner(group_extra_revision_table), ], ) vdm.sqlalchemy.modify_base_object_mapper(GroupExtra, core.Revision, core.State) GroupExtraRevision = vdm.sqlalchemy.create_object_version( meta.mapper, GroupExtra, group_extra_revision_table)
class RatingValueException(Exception): pass # import here to prevent circular import import tag meta.mapper(Package, package_table, properties={ # delete-orphan on cascade does NOT work! # Why? Answer: because of way SQLAlchemy/our code works there are points # where PackageTag object is created *and* flushed but does not yet have # the package_id set (this cause us other problems ...). Some time later a # second commit happens in which the package_id is correctly set. # However after first commit PackageTag does not have Package and # delete-orphan kicks in to remove it! 'package_tags':orm.relation(tag.PackageTag, backref='package', cascade='all, delete', #, delete-orphan', ), }, order_by=package_table.c.name, extension=[vdm.sqlalchemy.Revisioner(package_revision_table), extension.PluginMapperExtension(), ], ) vdm.sqlalchemy.modify_base_object_mapper(Package, core.Revision, core.State) PackageRevision = vdm.sqlalchemy.create_object_version(meta.mapper, Package, package_revision_table) def related_packages(self): return [self.continuity]
class Activity(domain_object.DomainObject): def __init__(self, user_id, object_id, revision_id, activity_type, data=None): self.id = _types.make_uuid() self.timestamp = datetime.datetime.now() self.user_id = user_id self.object_id = object_id self.revision_id = revision_id self.activity_type = activity_type if data is None: self.data = {} else: self.data = data meta.mapper(Activity, activity_table) class ActivityDetail(domain_object.DomainObject): def __init__(self, activity_id, object_id, object_type, activity_type, data=None): self.activity_id = activity_id self.object_id = object_id self.object_type = object_type self.activity_type = activity_type if data is None: self.data = {} else: self.data = data meta.mapper(ActivityDetail, activity_detail_table, properties = {
else: query = sqlalchemy_query qstr = '%' + querystr + '%' filters = [ cls.name.ilike(qstr), cls.fullname.ilike(qstr), ] # sysadmins can search on user emails import ckan.authz as authz if user_name and authz.is_sysadmin(user_name): filters.append(cls.email.ilike(qstr)) query = query.filter(or_(*filters)) return query @classmethod def user_ids_for_name_or_id(self, user_list=[]): ''' This function returns a list of ids from an input that can be a list of names or ids ''' query = meta.Session.query(self.id) query = query.filter(or_(self.name.in_(user_list), self.id.in_(user_list))) return [user.id for user in query.all()] meta.mapper(User, user_table, properties={'password': synonym('_password', map_column=True)}, order_by=user_table.c.name)
Tag.name == tag_name)) query = query.autoflush(autoflush) return query.one()[0] def related_packages(self): return [self.package] meta.mapper( Tag, tag_table, properties={ 'package_tags': relation( PackageTag, backref='tag', cascade='all, delete, delete-orphan', ), 'vocabulary': relation(vocabulary.Vocabulary, order_by=tag_table.c.name) }, order_by=tag_table.c.name, ) meta.mapper( PackageTag, package_tag_table, properties={ 'pkg': relation( _package.Package,
if not obj_rev.revision in results: results[obj_rev.revision] = [] results[obj_rev.revision].append(obj_rev) result_list = results.items() ourcmp = lambda rev_tuple1, rev_tuple2: \ cmp(rev_tuple2[0].timestamp, rev_tuple1[0].timestamp) return sorted(result_list, cmp=ourcmp) def __repr__(self): return '<Group %s>' % self.name meta.mapper( Group, group_table, extension=[ vdm.sqlalchemy.Revisioner(group_revision_table), ], ) vdm.sqlalchemy.modify_base_object_mapper(Group, core.Revision, core.State) GroupRevision = vdm.sqlalchemy.create_object_version(meta.mapper, Group, group_revision_table) meta.mapper( Member, member_table, properties={ 'group': orm.relation(Group, backref=orm.backref('member_all',
@classmethod def get_count_not_in_view_types(cls, view_types): """Returns the count of ResourceView not in the view types list""" query = ( meta.Session.query(ResourceView.view_type, sa.func.count(ResourceView.id)) .group_by(ResourceView.view_type) .filter(sa.not_(ResourceView.view_type.in_(view_types))) ) return query.all() @classmethod def delete_not_in_view_types(cls, view_types): """Delete the Resource Views not in the received view types list""" query = meta.Session.query(ResourceView).filter(sa.not_(ResourceView.view_type.in_(view_types))) return query.delete(synchronize_session="fetch") @classmethod def delete_all(cls, view_types=[]): """Delete all Resource Views, or all of a particular type""" query = meta.Session.query(ResourceView) if view_types: query = query.filter(ResourceView.view_type.in_(view_types)) return query.delete(synchronize_session="fetch") meta.mapper(ResourceView, resource_view_table)
assert isinstance(_domain_object, domain_object.DomainObject) if isinstance(_domain_object, _package.Package): q = meta.Session.query(PackageRole).filter_by(package=_domain_object) elif isinstance(_domain_object, group.Group): q = meta.Session.query(GroupRole).filter_by(group=_domain_object) else: raise NotImplementedError() user_roles = q.all() for user_role in user_roles: meta.Session.delete(user_role) ## ====================================== ## Mappers meta.mapper(RoleAction, role_action_table) meta.mapper( UserObjectRole, user_object_role_table, polymorphic_on=user_object_role_table.c.context, polymorphic_identity=u'user_object', properties={ 'user': orm.relation(_user.User, backref=orm.backref('roles', cascade='all, delete, delete-orphan')) }, order_by=[user_object_role_table.c.id], )
meta.metadata, Column('id', types.UnicodeText, primary_key=True, default=_types.make_uuid), Column('user_id', types.UnicodeText, ForeignKey('user.id')), Column('user_ip_address', types.UnicodeText), # alternative to user_id if not logged in Column('package_id', types.UnicodeText, ForeignKey('package.id')), Column('rating', types.Float), Column('created', types.DateTime, default=datetime.datetime.now), ) class Rating(domain_object.DomainObject): pass meta.mapper( Rating, rating_table, properties={ 'user': orm.relation(user.User, backref=orm.backref( 'ratings', cascade='all, delete, delete-orphan')), 'package': orm.relation(_package.Package, backref=orm.backref( 'ratings', cascade='all, delete, delete-orphan')), }, )
vdm.sqlalchemy.make_table_stateful(group_extra_table) group_extra_revision_table = core.make_revisioned_table(group_extra_table) class GroupExtra(vdm.sqlalchemy.RevisionedObjectMixin, vdm.sqlalchemy.StatefulObjectMixin, domain_object.DomainObject): pass meta.mapper( GroupExtra, group_extra_table, properties={ "group": orm.relation( group.Group, backref=orm.backref( "_extras", collection_class=orm.collections.attribute_mapped_collection(u"key"), cascade="all, delete, delete-orphan", ), ) }, order_by=[group_extra_table.c.group_id, group_extra_table.c.key], extension=[vdm.sqlalchemy.Revisioner(group_extra_revision_table)], ) vdm.sqlalchemy.modify_base_object_mapper(GroupExtra, core.Revision, core.State) GroupExtraRevision = vdm.sqlalchemy.create_object_version(meta.mapper, GroupExtra, group_extra_revision_table) def _create_extra(key, value): return GroupExtra(key=unicode(key), value=value)
res_dict = ckan.lib.dictization.table_dictize(self, context={"model": model}) return activity.ActivityDetail(activity_id, self.id, u"Resource", activity_type, {"resource": res_dict}) ## Mappers meta.mapper( Resource, resource_table, properties={ "package": orm.relation( Package, # all resources including deleted # formally package_resources_all backref=orm.backref( "resources_all", collection_class=ordering_list("position"), cascade="all, delete", order_by=resource_table.c.position, ), ) }, order_by=[resource_table.c.package_id], extension=[vdm.sqlalchemy.Revisioner(resource_revision_table), extension.PluginMapperExtension()], ) ## VDM vdm.sqlalchemy.modify_base_object_mapper(Resource, core.Revision, core.State) ResourceRevision = vdm.sqlalchemy.create_object_version(meta.mapper, Resource, resource_revision_table)
__all__ = ['Rating', 'MIN_RATING', 'MAX_RATING'] MIN_RATING = 1.0 MAX_RATING = 5.0 rating_table = Table('rating', meta.metadata, Column('id', types.UnicodeText, primary_key=True, default=_types.make_uuid), Column('user_id', types.UnicodeText, ForeignKey('user.id')), Column('user_ip_address', types.UnicodeText), # alternative to user_id if not logged in Column('package_id', types.UnicodeText, ForeignKey('package.id')), Column('rating', types.Float), Column('created', types.DateTime, default=datetime.datetime.now), ) class Rating(domain_object.DomainObject): pass meta.mapper(Rating, rating_table, properties={ 'user': orm.relation(user.User, backref=orm.backref('ratings', cascade='all, delete, delete-orphan' )), 'package': orm.relation(_package.Package, backref=orm.backref('ratings', cascade='all, delete, delete-orphan' )), }, )
) if capacity: q = q.filter(model.Member.capacity == capacity) return q.all() if "_groups" not in self.__dict__: self._groups = q.all() groups = self._groups if group_type: groups = [g for g in groups if g.type == group_type] return groups @classmethod def search(cls, querystr, sqlalchemy_query=None): """Search name, fullname, email and openid. """ if sqlalchemy_query is None: query = meta.Session.query(cls) else: query = sqlalchemy_query qstr = "%" + querystr + "%" query = query.filter( or_(cls.name.ilike(qstr), cls.fullname.ilike(qstr), cls.openid.ilike(qstr), cls.email.ilike(qstr)) ) return query meta.mapper( User, user_table, properties={"password": synonym("_password", map_column=True)}, order_by=user_table.c.name )
def deactivate(self, package): related_ds = meta.Session.query(RelatedDataset).\ filter(RelatedDataset.dataset_id==package.id).\ filter(RelatedDataset.status=='active').first() if related_ds: related_ds.status = 'inactive' meta.Session.commit() # We have avoided using SQLAlchemy association objects see # http://bit.ly/sqlalchemy_association_object by only having the # relation be for 'active' related objects. For non-active states # the caller will have to use get_for_dataset() in Related. meta.mapper(RelatedDataset, related_dataset_table, properties={ 'related': orm.relation(Related), 'dataset': orm.relation(_package.Package) }) meta.mapper( Related, related_table, properties={ 'datasets': orm.relation( _package.Package, backref=orm.backref('related'), secondary=related_dataset_table, secondaryjoin=and_( related_dataset_table.c.dataset_id == _package.Package.id, RelatedDataset.status == 'active')) })
'ckan.extra_resource_group_fields', '').split() for field in cls.extra_columns: setattr(cls, field, DictProxy(field, 'extras')) return cls.extra_columns ## Mappers meta.mapper(Resource, resource_table, properties={ 'resource_group': orm.relation( ResourceGroup, # all resources including deleted # formally package_resources_all backref=orm.backref('resources_all', collection_class=ordering_list('position'), cascade='all, delete', order_by=resource_table.c.position, ), ) }, order_by=[resource_table.c.resource_group_id], extension=[vdm.sqlalchemy.Revisioner(resource_revision_table), extension.PluginMapperExtension(), ], ) meta.mapper(ResourceGroup, resource_group_table, properties={ 'package': orm.relation( _package.Package, # all resources including deleted backref=orm.backref('resource_groups_all', cascade='all, delete, delete-orphan',
user_following_user_table = sqlalchemy.Table('user_following_user', meta.metadata, sqlalchemy.Column('follower_id', sqlalchemy.types.UnicodeText, sqlalchemy.ForeignKey('user.id', onupdate='CASCADE', ondelete='CASCADE'), primary_key=True, nullable=False), sqlalchemy.Column('object_id', sqlalchemy.types.UnicodeText, sqlalchemy.ForeignKey('user.id', onupdate='CASCADE', ondelete='CASCADE'), primary_key=True, nullable=False), sqlalchemy.Column('datetime', sqlalchemy.types.DateTime, nullable=False), ) meta.mapper(UserFollowingUser, user_following_user_table) class UserFollowingDataset(domain_object.DomainObject): '''A many-many relationship between users and datasets (packages). A relationship between a user (the follower) and a dataset (the object), that means that the user is currently following the dataset. ''' def __init__(self, follower_id, object_id): self.follower_id = follower_id self.object_id = object_id self.datetime = datetime.datetime.now() @classmethod def get(self, follower_id, object_id):
return activity.ActivityDetail(activity_id, self.id, u"Resource", activity_type, {'resource': res_dict}) ## Mappers meta.mapper(Resource, resource_table, properties={ 'package': orm.relation( Package, # all resources including deleted # formally package_resources_all backref=orm.backref('resources_all', collection_class=ordering_list('position'), cascade='all, delete', order_by=resource_table.c.position, ), ) }, extension=[vdm.sqlalchemy.Revisioner(resource_revision_table), extension.PluginMapperExtension(), ], ) ## VDM vdm.sqlalchemy.modify_base_object_mapper(Resource, core.Revision, core.State) ResourceRevision = vdm.sqlalchemy.create_object_version( meta.mapper, Resource, resource_revision_table)
q = q.filter(AuthorizationGroup.users.contains(user)) return q.count() == 1 def add_user_to_authorization_group(user, authorization_group, role): assert not user_in_authorization_group(user, authorization_group) from authz import add_user_to_role meta.Session.add(authorization_group) authorization_group.users.append(user) add_user_to_role(user, role, authorization_group) def remove_user_from_authorization_group(user, authorization_group): assert user_in_authorization_group(user, authorization_group) from authz import remove_user_from_role, AuthorizationGroupRole meta.Session.add(authorization_group) authorization_group.users.remove(user) q = meta.Session.query(AuthorizationGroupRole) q = q.filter_by(authorization_group=authorization_group, user=user) for agr in q: remove_user_from_role(user, agr.role, authorization_group) meta.mapper(AuthorizationGroup, authorization_group_table, properties={ 'users': orm.relation(user.User, lazy=True, secondary=authorization_group_user_table, backref=orm.backref('authorization_groups', lazy=True)) }, order_by=authorization_group_table.c.name) meta.mapper(AuthorizationGroupUser, authorization_group_user_table)
activity_type = 'deleted' data_dict = ckan.lib.dictization.table_dictize(self, context={'model': model}) return activity.ActivityDetail(activity_id, self.id, u"PackageExtra", activity_type, {'package_extra': data_dict}) meta.mapper(PackageExtra, package_extra_table, properties={ 'package': orm.relation(_package.Package, backref=orm.backref('_extras', collection_class=orm.collections.attribute_mapped_collection(u'key'), cascade='all, delete, delete-orphan', ), ), 'package_no_state': orm.relation(_package.Package, backref=orm.backref('extras_list', cascade='all, delete, delete-orphan', ), ) }, order_by=[package_extra_table.c.package_id, package_extra_table.c.key], extension=[vdm.sqlalchemy.Revisioner(extra_revision_table), extension.PluginMapperExtension(), ], ) vdm.sqlalchemy.modify_base_object_mapper(PackageExtra, core.Revision, core.State) PackageExtraRevision= vdm.sqlalchemy.create_object_version(meta.mapper, PackageExtra, extra_revision_table) PackageExtraRevision.related_packages = lambda self: [self.continuity.package]
user_following_user_table = sqlalchemy.Table('user_following_user', meta.metadata, sqlalchemy.Column('follower_id', sqlalchemy.types.UnicodeText, sqlalchemy.ForeignKey('user.id', onupdate='CASCADE', ondelete='CASCADE'), primary_key=True, nullable=False), sqlalchemy.Column('object_id', sqlalchemy.types.UnicodeText, sqlalchemy.ForeignKey('user.id', onupdate='CASCADE', ondelete='CASCADE'), primary_key=True, nullable=False), sqlalchemy.Column('datetime', sqlalchemy.types.DateTime, nullable=False), ) meta.mapper(UserFollowingUser, user_following_user_table) class UserFollowingDataset(ModelFollowingModel): '''A many-many relationship between users and datasets (packages). A relationship between a user (the follower) and a dataset (the object), that means that the user is currently following the dataset. ''' @classmethod def _follower_class(cls): return ckan.model.User @classmethod def _object_class(cls): return ckan.model.Package
qstr = '%' + querystr + '%' filters = [ cls.name.ilike(qstr), cls.fullname.ilike(qstr), cls.openid.ilike(qstr), ] # sysadmins can search on user emails import ckan.authz as authz if user_name and authz.is_sysadmin(user_name): filters.append(cls.email.ilike(qstr)) query = query.filter(or_(*filters)) return query @classmethod def user_ids_for_name_or_id(self, user_list=[]): ''' This function returns a list of ids from an input that can be a list of names or ids ''' query = meta.Session.query(self.id) query = query.filter( or_(self.name.in_(user_list), self.id.in_(user_list))) return [user.id for user in query.all()] meta.mapper(User, user_table, properties={'password': synonym('_password', map_column=True)}, order_by=user_table.c.name)
import sqlalchemy from meta import Table, Column, UnicodeText, ForeignKey, mapper, metadata __all__ = ['package_search_table'] def setup_db(event, schema_item, engine): sql = 'ALTER TABLE package_search ADD COLUMN search_vector tsvector' res = engine.execute(sql) res.close() package_search_table = Table('package_search', metadata, Column('package_id', UnicodeText, ForeignKey('package.id'), primary_key=True), ) class PackageSearch(object): pass # We need this mapper so that Package can delete orphaned package_search rows mapper(PackageSearch, package_search_table, properties={}) package_search_table.append_ddl_listener('after-create', setup_db)
@classmethod def reverse_type(cls, forward_or_reverse_type): for fwd, rev in cls.types: if fwd == forward_or_reverse_type: return rev if rev == forward_or_reverse_type: return fwd @classmethod def make_type_printable(cls, type_): for i, types in enumerate(cls.types): for j in range(2): if type_ == types[j]: return cls.types_printable[i][j] raise TypeError, type_ meta.mapper(PackageRelationship, package_relationship_table, properties={ 'subject':orm.relation(_package.Package, primaryjoin=\ package_relationship_table.c.subject_package_id==_package.Package.id, backref='relationships_as_subject'), 'object':orm.relation(_package.Package, primaryjoin=package_relationship_table.c.object_package_id==_package.Package.id, backref='relationships_as_object'), }, extension = [vdm.sqlalchemy.Revisioner(package_relationship_revision_table)] ) vdm.sqlalchemy.modify_base_object_mapper(PackageRelationship, core.Revision, core.State) PackageRelationshipRevision = vdm.sqlalchemy.create_object_version( meta.mapper, PackageRelationship, package_relationship_revision_table)
) class Dashboard(object): '''Saved data used for the user's dashboard.''' def __init__(self, user_id): self.user_id = user_id self.activity_stream_last_viewed = datetime.datetime.utcnow() self.email_last_sent = datetime.datetime.utcnow() @classmethod def get(cls, user_id): '''Return the Dashboard object for the given user_id. If there's no dashboard row in the database for this user_id, a fresh one will be created and returned. ''' query = meta.Session.query(Dashboard) query = query.filter(Dashboard.user_id == user_id) try: row = query.one() except sqlalchemy.orm.exc.NoResultFound: row = Dashboard(user_id) meta.Session.add(row) meta.Session.commit() return row meta.mapper(Dashboard, dashboard_table)
# import here to prevent circular import import tag meta.mapper( Package, package_table, properties={ # delete-orphan on cascade does NOT work! # Why? Answer: because of way SQLAlchemy/our code works there are points # where PackageTag object is created *and* flushed but does not yet have # the package_id set (this cause us other problems ...). Some time later a # second commit happens in which the package_id is correctly set. # However after first commit PackageTag does not have Package and # delete-orphan kicks in to remove it! 'package_tags': orm.relation( tag.PackageTag, backref='package', cascade='all, delete', #, delete-orphan', ), }, order_by=package_table.c.name, extension=[ vdm.sqlalchemy.Revisioner(package_revision_table), extension.PluginMapperExtension(), ], ) vdm.sqlalchemy.modify_base_object_mapper(Package, core.Revision, core.State) PackageRevision = vdm.sqlalchemy.create_object_version(meta.mapper, Package, package_revision_table)
self.user_id = user_id self.activity_stream_last_viewed = datetime.datetime.now() @classmethod def get_activity_stream_last_viewed(cls, user_id): query = meta.Session.query(Dashboard) query = query.filter(Dashboard.user_id == user_id) try: row = query.one() return row.activity_stream_last_viewed except sqlalchemy.orm.exc.NoResultFound: # No dashboard row has been created for this user so they have no # activity_stream_last_viewed date. Return the oldest date we can # (i.e. all activities are new to this user). return datetime.datetime.min @classmethod def update_activity_stream_last_viewed(cls, user_id): query = meta.Session.query(Dashboard) query = query.filter(Dashboard.user_id == user_id) try: row = query.one() row.activity_stream_last_viewed = datetime.datetime.now() except sqlalchemy.orm.exc.NoResultFound: row = Dashboard(user_id) meta.Session.add(row) meta.Session.commit() meta.mapper(Dashboard, dashboard_table)
class Activity(domain_object.DomainObject): def __init__(self, user_id, object_id, revision_id, activity_type, data=None): self.id = _types.make_uuid() self.timestamp = datetime.datetime.now() self.user_id = user_id self.object_id = object_id self.revision_id = revision_id self.activity_type = activity_type if data is None: self.data = {} else: self.data = data meta.mapper(Activity, activity_table) class ActivityDetail(domain_object.DomainObject): def __init__(self, activity_id, object_id, object_type, activity_type, data=None): self.activity_id = activity_id self.object_id = object_id self.object_type = object_type self.activity_type = activity_type if data is None: self.data = {} else: self.data = data @classmethod def by_activity_id(cls, activity_id):
Column('name', types.Unicode(VOCABULARY_NAME_MAX_LENGTH), nullable=False, unique=True), ) class Vocabulary(domain_object.DomainObject): def __init__(self, name): self.id = _types.make_uuid() self.name = name @classmethod def get(cls, id_or_name): '''Return a Vocabulary object referenced by its id or name, or None if there is no vocabulary with the given id or name. ''' query = meta.Session.query(Vocabulary) query = query.filter(Vocabulary.id == id_or_name) vocab = query.first() if vocab is None: vocab = Vocabulary.by_name(id_or_name) return vocab @property def tags(self): query = meta.Session.query(tag.Tag) return query.filter(tag.Tag.vocabulary_id == self.id) meta.mapper(Vocabulary, vocabulary_table)
from meta import Table, Column, UnicodeText, ForeignKey, mapper, metadata __all__ = ['package_search_table', 'PackageSearch'] def setup_db(event, schema_item, engine): sql = 'ALTER TABLE package_search ADD COLUMN search_vector tsvector' res = engine.execute(sql) res.close() package_search_table = Table( 'package_search', metadata, Column('package_id', UnicodeText, ForeignKey('package.id'), primary_key=True), ) class PackageSearch(object): pass # We need this mapper so that Package can delete orphaned package_search rows mapper(PackageSearch, package_search_table, properties={}) package_search_table.append_ddl_listener('after-create', setup_db)
@classmethod def get_count_not_in_view_types(cls, view_types): '''Returns the count of ResourceView not in the view types list''' query = meta.Session.query(ResourceView.view_type, sa.func.count(ResourceView.id)) \ .group_by(ResourceView.view_type) \ .filter(sa.not_(ResourceView.view_type.in_(view_types))) return query.all() @classmethod def delete_not_in_view_types(cls, view_types): '''Delete the Resource Views not in the received view types list''' query = meta.Session.query(ResourceView) \ .filter(sa.not_(ResourceView.view_type.in_(view_types))) return query.delete(synchronize_session='fetch') @classmethod def delete_all(cls, view_types=[]): '''Delete all Resource Views, or all of a particular type''' query = meta.Session.query(ResourceView) if view_types: query = query.filter(ResourceView.view_type.in_(view_types)) return query.delete(synchronize_session='fetch') meta.mapper(ResourceView, resource_view_table)
obj_revisions = meta.Session.query(rev_class).\ filter_by(group_id=self.id).all() for obj_rev in obj_revisions: if not obj_rev.revision in results: results[obj_rev.revision] = [] results[obj_rev.revision].append(obj_rev) result_list = results.items() ourcmp = lambda rev_tuple1, rev_tuple2: \ cmp(rev_tuple2[0].timestamp, rev_tuple1[0].timestamp) return sorted(result_list, cmp=ourcmp) def __repr__(self): return '<Group %s>' % self.name meta.mapper(Group, group_table, extension=[vdm.sqlalchemy.Revisioner(group_revision_table), ], ) vdm.sqlalchemy.modify_base_object_mapper(Group, core.Revision, core.State) GroupRevision = vdm.sqlalchemy.create_object_version(meta.mapper, Group, group_revision_table) meta.mapper(Member, member_table, properties={ 'group': orm.relation(Group, backref=orm.backref('member_all', cascade='all, delete-orphan')), }, extension=[vdm.sqlalchemy.Revisioner(member_revision_table), ], ) vdm.sqlalchemy.modify_base_object_mapper(Member, core.Revision, core.State)
extra_revision_table = \ core.make_revisioned_table(package_extra_table, frozen=True) class PackageExtra( core.StatefulObjectMixin, domain_object.DomainObject): def related_packages(self): return [self.package] meta.mapper(PackageExtra, package_extra_table, properties={ 'package': orm.relation(_package.Package, backref=orm.backref('_extras', collection_class=orm.collections.attribute_mapped_collection(u'key'), cascade='all, delete, delete-orphan', ), ), }, order_by=[package_extra_table.c.package_id, package_extra_table.c.key], extension=[extension.PluginMapperExtension()], ) def _create_extra(key, value): return PackageExtra(key=text_type(key), value=value) _package.Package.extras = association_proxy( '_extras', 'value', creator=_create_extra)
import domain_object __all__ = ['TaskStatus', 'task_status_table'] task_status_table = Table( 'task_status', meta.metadata, Column('id', types.UnicodeText, primary_key=True, default=_types.make_uuid), Column('entity_id', types.UnicodeText, nullable=False), Column('entity_type', types.UnicodeText, nullable=False), Column('task_type', types.UnicodeText, nullable=False), Column('key', types.UnicodeText, nullable=False), Column('value', types.UnicodeText, nullable=False), Column('state', types.UnicodeText), Column('error', types.UnicodeText), Column('last_updated', types.DateTime, default=datetime.now), UniqueConstraint('entity_id', 'task_type', 'key')) class TaskStatus(domain_object.DomainObject): @classmethod def get(cls, reference): '''Returns a task status object referenced by its id.''' if not reference: return None task = meta.Session.query(cls).get(reference) return task meta.mapper(TaskStatus, task_status_table)
def add_package_by_name(self, package_name): if not package_name: return package = _package.Package.by_name(package_name) assert package if not package in self.packages(): member = Member(group=self, table_id=package.id, table_name='package') meta.Session.add(member) def __repr__(self): return '<Group %s>' % self.name meta.mapper(Group, group_table) meta.mapper(Member, member_table, properties={ 'group': orm.relation(Group, backref=orm.backref( 'member_all', cascade='all, delete-orphan')), }) # Should there arise a bug that allows loops in the group hierarchy, then it # will lead to infinite recursion, tieing up postgres processes at 100%, and # the server will suffer. To avoid ever failing this badly, we put in this # limit on recursion. MAX_RECURSES = 8
import meta import types as _types import domain_object __all__ = ['TaskStatus', 'task_status_table'] task_status_table = Table('task_status', meta.metadata, Column('id', types.UnicodeText, primary_key=True, default=_types.make_uuid), Column('entity_id', types.UnicodeText, nullable=False), Column('entity_type', types.UnicodeText, nullable=False), Column('task_type', types.UnicodeText, nullable=False), Column('key', types.UnicodeText, nullable=False), Column('value', types.UnicodeText, nullable=False), Column('state', types.UnicodeText), Column('error', types.UnicodeText), Column('last_updated', types.DateTime, default=datetime.now), UniqueConstraint('entity_id', 'task_type', 'key') ) class TaskStatus(domain_object.DomainObject): @classmethod def get(cls, reference): '''Returns a task status object referenced by its id.''' if not reference: return None task = meta.Session.query(cls).get(reference) return task meta.mapper(TaskStatus, task_status_table)
""" query = meta.Session.query(RelatedDataset).\ filter(RelatedDataset.dataset_id==package.id).\ filter(RelatedDataset.status==status).all() return query def deactivate(self, package): related_ds = meta.Session.query(RelatedDataset).\ filter(RelatedDataset.dataset_id==package.id).\ filter(RelatedDataset.status=='active').first() if related_ds: related_ds.status = 'inactive' meta.Session.commit() # We have avoided using SQLAlchemy association objects see # http://bit.ly/sqlalchemy_association_object by only having the # relation be for 'active' related objects. For non-active states # the caller will have to use get_for_dataset() in Related. meta.mapper(RelatedDataset, related_dataset_table, properties={ 'related': orm.relation(Related), 'dataset': orm.relation(_package.Package) }) meta.mapper(Related, related_table, properties={ 'datasets': orm.relation(_package.Package, backref=orm.backref('related'), secondary=related_dataset_table, secondaryjoin=and_(related_dataset_table.c.dataset_id==_package.Package.id, RelatedDataset.status=='active')) })
.filter(Tag.name==tag_name)) else: query = (meta.Session.query(PackageTag) .filter(_package.Package.name==package_name) .filter(Tag.name==tag_name)) query = query.autoflush(autoflush) return query.one()[0] def related_packages(self): return [self.package] meta.mapper(Tag, tag_table, properties={ 'package_tags': relation(PackageTag, backref='tag', cascade='all, delete, delete-orphan', ), 'vocabulary': relation(vocabulary.Vocabulary, order_by=tag_table.c.name) }, order_by=tag_table.c.name, ) meta.mapper(PackageTag, package_tag_table, properties={ 'pkg':relation(_package.Package, backref='package_tag_all', cascade='none', ) }, order_by=package_tag_table.c.id, extension=[vdm.sqlalchemy.Revisioner(package_tag_revision_table), _extension.PluginMapperExtension(), ], )
Column('value', types.UnicodeText), Column('state', types.UnicodeText, default=core.State.ACTIVE), ) # Define the group_extra_revision table, but no need to map it, as it is only # used by migrate_package_activity.py group_extra_revision_table = \ core.make_revisioned_table(group_extra_table, frozen=True) class GroupExtra(core.StatefulObjectMixin, domain_object.DomainObject): pass meta.mapper(GroupExtra, group_extra_table, properties={ 'group': orm.relation(group.Group, backref=orm.backref('_extras', collection_class=orm.collections.attribute_mapped_collection(u'key'), cascade='all, delete, delete-orphan', ), ) }, order_by=[group_extra_table.c.group_id, group_extra_table.c.key], ) def _create_extra(key, value): return GroupExtra(key=text_type(key), value=value) group.Group.extras = association_proxy( '_extras', 'value', creator=_create_extra)
assert isinstance(_domain_object, domain_object.DomainObject) if isinstance(_domain_object, _package.Package): q = meta.Session.query(PackageRole).filter_by(package=_domain_object) elif isinstance(_domain_object, group.Group): q = meta.Session.query(GroupRole).filter_by(group=_domain_object) else: raise NotImplementedError() user_roles = q.all() for user_role in user_roles: meta.Session.delete(user_role) ## ====================================== ## Mappers meta.mapper(RoleAction, role_action_table) meta.mapper(UserObjectRole, user_object_role_table, polymorphic_on=user_object_role_table.c.context, polymorphic_identity=u'user_object', properties={ 'user': orm.relation(_user.User, backref=orm.backref('roles', cascade='all, delete, delete-orphan' ) ), 'authorized_group': orm.relation(auth_group.AuthorizationGroup, backref=orm.backref('authorized_roles', cascade='all, delete, delete-orphan' ) )
system_info_revision_table = core.make_revisioned_table(system_info_table) class SystemInfo(vdm.sqlalchemy.RevisionedObjectMixin, core.StatefulObjectMixin, domain_object.DomainObject): def __init__(self, key, value): super(SystemInfo, self).__init__() self.key = key self.value = text_type(value) meta.mapper(SystemInfo, system_info_table, extension=[ vdm.sqlalchemy.Revisioner(system_info_revision_table), ]) vdm.sqlalchemy.modify_base_object_mapper(SystemInfo, core.Revision, core.State) SystemInfoRevision = vdm.sqlalchemy.create_object_version( meta.mapper, SystemInfo, system_info_revision_table) def get_system_info(key, default=None): ''' get data from system_info table ''' from sqlalchemy.exc import ProgrammingError try: obj = meta.Session.query(SystemInfo).filter_by(key=key).first() if obj: return obj.value
Column('count', types.Integer, nullable=False), Column('running_total', types.Integer, nullable=False), Column('recent_views', types.Integer, nullable=False), Column('tracking_date', types.DateTime), ) class TrackingSummary(domain_object.DomainObject): @classmethod def get_for_package(cls, package_id): obj = meta.Session.query(cls).autoflush(False) obj = obj.filter_by(package_id=package_id) if meta.Session.query(obj.exists()).scalar(): data = obj.order_by(text('tracking_date desc')).first() return {'total': data.running_total, 'recent': data.recent_views} return {'total': 0, 'recent': 0} @classmethod def get_for_resource(cls, url): obj = meta.Session.query(cls).autoflush(False) data = obj.filter_by(url=url).order_by( text('tracking_date desc')).first() if data: return {'total': data.running_total, 'recent': data.recent_views} return {'total': 0, 'recent': 0} meta.mapper(TrackingSummary, tracking_summary_table)
Column('id', types.Integer(), primary_key=True, nullable=False), Column('key', types.Unicode(100), unique=True, nullable=False), Column('value', types.UnicodeText), ) system_info_revision_table = core.make_revisioned_table(system_info_table) class SystemInfo(domain_object.DomainObject): def __init__(self, key, value): self.key = key self.value = unicode(value) meta.mapper(SystemInfo, system_info_table) def get_system_info(key, default=None): ''' get data from system_info table ''' obj = meta.Session.query(SystemInfo).filter_by(key=key).first() if obj: return obj.value else: return default def delete_system_info(key, default=None): ''' delete data from system_info table ''' obj = meta.Session.query(SystemInfo).filter_by(key=key).first() if obj:
## Mappers meta.mapper( Resource, resource_table, properties={ 'resource_group': orm.relation( ResourceGroup, # all resources including deleted # formally package_resources_all backref=orm.backref( 'resources_all', collection_class=ordering_list('position'), cascade='all, delete', order_by=resource_table.c.position, ), ) }, order_by=[resource_table.c.resource_group_id], extension=[ vdm.sqlalchemy.Revisioner(resource_revision_table), extension.PluginMapperExtension(), ], ) meta.mapper( ResourceGroup, resource_group_table,
class SystemInfo(vdm.sqlalchemy.RevisionedObjectMixin, vdm.sqlalchemy.StatefulObjectMixin, domain_object.DomainObject): def __init__(self, key, value): super(SystemInfo, self).__init__() self.key = key self.value = unicode(value) meta.mapper(SystemInfo, system_info_table, extension=[ vdm.sqlalchemy.Revisioner(system_info_revision_table), ]) vdm.sqlalchemy.modify_base_object_mapper(SystemInfo, core.Revision, core.State) SystemInfoRevision = vdm.sqlalchemy.create_object_version(meta.mapper, SystemInfo, system_info_revision_table) def get_system_info(key, default=None): ''' get data from system_info table ''' from sqlalchemy.exc import ProgrammingError try: obj = meta.Session.query(SystemInfo).filter_by(key=key).first() if obj: return obj.value
self.timestamp = datetime.datetime.utcnow() self.user_id = user_id self.last_run = None self.search_string = search_string self.last_results = [] saved_search_table = Table( 'saved_search', meta.metadata, Column('id', types.UnicodeText, primary_key=True, default=_types.make_uuid), Column('timestamp', types.DateTime), Column('user_id', types.UnicodeText), Column('last_run', types.DateTime), Column('search_string', types.UnicodeText), Column('last_results', ARRAY(TEXT))) meta.mapper(SavedSearch, saved_search_table) def _make_parameters(query_string): parts = query_string.split("&") res = {} for part in parts: s = part.split("=") if len(s) > 1: res[s[0]] = s[1] return res def user_saved_searches_list(user_id): '''Return an SQLAlchemy query for all saved searches from user_id.''' import ckan.model as model
meta.mapper( PackageExtra, package_extra_table, properties={ 'package': orm.relation( _package.Package, backref=orm.backref( '_extras', collection_class=orm.collections.attribute_mapped_collection( u'key'), cascade='all, delete, delete-orphan', ), ), 'package_no_state': orm.relation( _package.Package, backref=orm.backref( 'extras_list', cascade='all, delete, delete-orphan', ), ) }, order_by=[package_extra_table.c.package_id, package_extra_table.c.key], extension=[ vdm.sqlalchemy.Revisioner(extra_revision_table), extension.PluginMapperExtension(), ], )
@classmethod def forward_to_reverse_type(cls, forward_type): for fwd, rev in cls.types: if fwd == forward_type: return rev @classmethod def reverse_type(cls, forward_or_reverse_type): for fwd, rev in cls.types: if fwd == forward_or_reverse_type: return rev if rev == forward_or_reverse_type: return fwd @classmethod def make_type_printable(cls, type_): for i, types in enumerate(cls.types): for j in range(2): if type_ == types[j]: return cls.types_printable[i][j] raise TypeError(type_) meta.mapper(PackageRelationship, package_relationship_table, properties={ 'subject':orm.relation(_package.Package, primaryjoin=\ package_relationship_table.c.subject_package_id==_package.Package.id, backref='relationships_as_subject'), 'object':orm.relation(_package.Package, primaryjoin=package_relationship_table.c.object_package_id==_package.Package.id, backref='relationships_as_object'), })
revision_id, activity_type, data=None): self.id = _types.make_uuid() self.timestamp = datetime.datetime.now() self.user_id = user_id self.object_id = object_id self.revision_id = revision_id self.activity_type = activity_type if data is None: self.data = {} else: self.data = data meta.mapper(Activity, activity_table) class ActivityDetail(domain_object.DomainObject): def __init__(self, activity_id, object_id, object_type, activity_type, data=None): self.activity_id = activity_id self.object_id = object_id self.object_type = object_type self.activity_type = activity_type if data is None: self.data = {}
__all__ = ["Rating", "MIN_RATING", "MAX_RATING"] MIN_RATING = 1.0 MAX_RATING = 5.0 rating_table = Table( "rating", meta.metadata, Column("id", types.UnicodeText, primary_key=True, default=_types.make_uuid), Column("user_id", types.UnicodeText, ForeignKey("user.id")), Column("user_ip_address", types.UnicodeText), # alternative to user_id if not logged in Column("package_id", types.UnicodeText, ForeignKey("package.id")), Column("rating", types.Float), Column("created", types.DateTime, default=datetime.datetime.now), ) class Rating(domain_object.DomainObject): pass meta.mapper( Rating, rating_table, properties={ "user": orm.relation(user.User, backref=orm.backref("ratings", cascade="all, delete, delete-orphan")), "package": orm.relation(_package.Package, backref=orm.backref("ratings", cascade="all, delete, delete-orphan")), }, )
"vocabulary", meta.metadata, Column("id", types.UnicodeText, primary_key=True, default=_types.make_uuid), Column("name", types.Unicode(VOCABULARY_NAME_MAX_LENGTH), nullable=False, unique=True), ) class Vocabulary(domain_object.DomainObject): def __init__(self, name): self.id = _types.make_uuid() self.name = name @classmethod def get(cls, id_or_name): """Return a Vocabulary object referenced by its id or name, or None if there is no vocabulary with the given id or name. """ query = meta.Session.query(Vocabulary) query = query.filter(Vocabulary.id == id_or_name) vocab = query.first() if vocab is None: vocab = Vocabulary.by_name(id_or_name) return vocab @property def tags(self): query = meta.Session.query(tag.Tag) return query.filter(tag.Tag.vocabulary_id == self.id) meta.mapper(Vocabulary, vocabulary_table)
Column('state', types.UnicodeText, default=core.State.ACTIVE), ) class SystemInfo(core.StatefulObjectMixin, domain_object.DomainObject): def __init__(self, key, value): super(SystemInfo, self).__init__() self.key = key self.value = text_type(value) meta.mapper(SystemInfo, system_info_table) def get_system_info(key, default=None): ''' get data from system_info table ''' from sqlalchemy.exc import ProgrammingError try: obj = meta.Session.query(SystemInfo).filter_by(key=key).first() if obj: return obj.value except ProgrammingError: meta.Session.rollback() return default
Column('running_total', types.Integer, nullable=False), Column('recent_views', types.Integer, nullable=False), Column('tracking_date', types.DateTime), ) class TrackingSummary(domain_object.DomainObject): @classmethod def get_for_package(cls, package_id): obj = meta.Session.query(cls).autoflush(False) obj = obj.filter_by(package_id=package_id) data = obj.order_by('tracking_date desc').first() if data: return {'total' : data.running_total, 'recent': data.recent_views} return {'total' : 0, 'recent' : 0} @classmethod def get_for_resource(cls, url): obj = meta.Session.query(cls).autoflush(False) data = obj.filter_by(url=url).order_by('tracking_date desc').first() if data: return {'total' : data.running_total, 'recent': data.recent_views} return {'total' : 0, 'recent' : 0} meta.mapper(TrackingSummary, tracking_summary_table)
for class_ in [Member, GroupExtra]: rev_class = class_.__revision_class__ obj_revisions = meta.Session.query(rev_class).filter_by(group_id=self.id).all() for obj_rev in obj_revisions: if not obj_rev.revision in results: results[obj_rev.revision] = [] results[obj_rev.revision].append(obj_rev) result_list = results.items() ourcmp = lambda rev_tuple1, rev_tuple2: cmp(rev_tuple2[0].timestamp, rev_tuple1[0].timestamp) return sorted(result_list, cmp=ourcmp) def __repr__(self): return "<Group %s>" % self.name meta.mapper(Group, group_table, extension=[vdm.sqlalchemy.Revisioner(group_revision_table)]) vdm.sqlalchemy.modify_base_object_mapper(Group, core.Revision, core.State) GroupRevision = vdm.sqlalchemy.create_object_version(meta.mapper, Group, group_revision_table) meta.mapper( Member, member_table, properties={"group": orm.relation(Group, backref=orm.backref("member_all", cascade="all, delete-orphan"))}, extension=[vdm.sqlalchemy.Revisioner(member_revision_table)], ) vdm.sqlalchemy.modify_base_object_mapper(Member, core.Revision, core.State) MemberRevision = vdm.sqlalchemy.create_object_version(meta.mapper, Member, member_revision_table)