class Schema(db.Model, IntBase): __tablename__ = 'schema' name = db.Column(db.Unicode()) label = db.Column(db.Unicode()) label_in = db.Column(db.Unicode()) label_out = db.Column(db.Unicode()) hidden = db.Column(db.Boolean()) obj = db.Column(db.Unicode()) attributes = db.relationship(Attribute, backref='schema', lazy='joined') properties = db.relationship(Property, backref='schema', lazy='dynamic') relations = db.relationship('Relation', backref='schema', lazy='dynamic') project_id = db.Column(db.Integer, db.ForeignKey('project.id')) def get_attribute(self, name): for attribute in self.attributes: if attribute.name == name: return attribute @classmethod def by_name(cls, project, name): q = db.session.query(cls).filter_by(name=name) q = q.filter_by(project=project) return q.first() @classmethod def by_obj_name(cls, project, obj, name): q = db.session.query(cls) q = q.filter_by(project=project) q = q.filter_by(name=name) q = q.filter_by(obj=obj) return q.first()
class Property(db.Model, IntBase): __tablename__ = 'grano_property' schema_id = db.Column(db.Integer, db.ForeignKey('grano_schema.id')) attribute_id = db.Column(db.Integer, db.ForeignKey('grano_attribute.id')) author_id = db.Column(db.Integer, db.ForeignKey('grano_account.id')) entity_id = db.Column(db.Unicode(), db.ForeignKey('grano_entity.id'), index=True, nullable=True) relation_id = db.Column(db.Unicode(), db.ForeignKey('grano_relation.id'), index=True, nullable=True) name = db.Column(db.Unicode(), index=True) value_string = db.Column(db.Unicode()) value_integer = db.Column(db.Integer()) value_float = db.Column(db.Float()) value_datetime = db.Column(db.DateTime()) value_boolean = db.Column(db.Boolean()) value_file_id = db.Column(db.Integer(), db.ForeignKey('grano_file.id')) source_url = db.Column(db.Unicode()) active = db.Column(db.Boolean()) @property def value(self): # check file column first since file uses both # value_string and value_file_id if self.value_file_id is not None: return self.value_file_id for column in Attribute.DATATYPES.values(): value = getattr(self, column) if value is not None: return value def to_dict_index(self): data = {'value': self.value, 'source_url': self.source_url} if self.value_file_id is not None: data['file_url'] = self.value_string return data def to_dict_kv(self): return self.name, self.to_dict_index() def to_dict(self): name, data = self.to_dict_index() data['id'] = self.id data['name'] = name data['created_at'] = self.created_at data['updated_at'] = self.updated_at data['active'] = self.active return data
class Attribute(db.Model, IntBase): __tablename__ = 'grano_attribute' DATATYPES = { 'string': 'value_string', 'integer': 'value_integer', 'float': 'value_float', 'datetime': 'value_datetime', 'boolean': 'value_boolean', 'file': 'value_file_id' } name = db.Column(db.Unicode()) label = db.Column(db.Unicode()) description = db.Column(db.Unicode()) hidden = db.Column(db.Boolean()) datatype = db.Column(db.Unicode()) schema_id = db.Column(db.Integer, db.ForeignKey('grano_schema.id')) properties = db.relationship('Property', backref='attribute', cascade='all, delete, delete-orphan', lazy='dynamic') @property def value_column(self): return self.DATATYPES.get(self.datatype) @classmethod def all_named(cls, name): q = db.session.query(cls) q = q.filter_by(name=name) return q.all() @classmethod def by_schema_and_name(cls, schema, name): q = db.session.query(cls) q = q.filter_by(schema=schema) q = q.filter_by(name=name) return q.first() def to_index(self): return { 'name': self.name, 'label': self.label, 'datatype': self.datatype } def to_dict(self): data = self.to_index() data['id'] = self.id data['hidden'] = self.hidden if self.description and len(self.description): data['description'] = self.description return data
class Attribute(db.Model, IntBase): __tablename__ = 'attribute' name = db.Column(db.Unicode()) label = db.Column(db.Unicode()) description = db.Column(db.Unicode()) hidden = db.Column(db.Boolean()) schema_id = db.Column(db.Integer, db.ForeignKey('schema.id')) @classmethod def by_name(cls, schema, name): q = db.session.query(cls) q = q.filter_by(schema=schema) q = q.filter_by(name=name) return q.first()
class EntityProperty(Property): __mapper_args__ = {'polymorphic_identity': 'entity'} entity_id = db.Column(db.Unicode(), db.ForeignKey('entity.id'), index=True) def _set_obj(self, obj): self.entity = obj
class RelationProperty(Property): __mapper_args__ = {'polymorphic_identity': 'relation'} relation_id = db.Column(db.Unicode(), db.ForeignKey('relation.id'), index=True) def _set_obj(self, obj): self.relation = obj
class Property(db.Model, IntBase): __tablename__ = 'property' schema_id = db.Column(db.Integer, db.ForeignKey('schema.id')) author_id = db.Column(db.Integer, db.ForeignKey('account.id')) name = db.Column(db.Unicode(), index=True) value = db.Column(db.Unicode()) source_url = db.Column(db.Unicode()) active = db.Column(db.Boolean()) obj = db.Column(db.String(20)) __mapper_args__ = {'polymorphic_on': obj} def to_dict(self): return { 'name': self.name, 'schema': self.schema.name, 'value': self.value, 'source_url': self.source_url, 'active': self.active }
class Schema(db.Model, IntBase): __tablename__ = 'grano_schema' name = db.Column(db.Unicode()) label = db.Column(db.Unicode()) hidden = db.Column(db.Boolean()) obj = db.Column(db.Unicode()) meta = db.Column(MutableDict.as_mutable(JSONEncodedDict)) project_id = db.Column(db.Integer, db.ForeignKey('grano_project.id')) parent_id = db.Column(db.Integer, db.ForeignKey('grano_schema.id'), nullable=True) local_attributes = db.relationship(Attribute, backref='schema', lazy='dynamic', cascade='all, delete, delete-orphan') relations = db.relationship('Relation', backref='schema', lazy='dynamic', cascade='all, delete, delete-orphan') entities = db.relationship('Entity', backref='schema', lazy='dynamic', cascade='all, delete, delete-orphan') children = db.relationship('Schema', lazy='dynamic', backref=db.backref('parent', remote_side='Schema.id')) @property def inherited_attributes(self): if self.parent is None: return [] return self.parent.attributes @property def attributes(self): return list(self.local_attributes) + self.inherited_attributes def get_attribute(self, name): for attribute in self.attributes: if attribute.name == name: return attribute def is_circular(self, path=None): if path is None: path = [] if self.name in path: return True elif self.parent is None: return False else: path.append(self.name) return self.parent.is_circular(path) def is_parent(self, other): if self.parent is None: return False if self.parent == other: return True return self.parent.is_parent(other) def common_parent(self, other): if self == other or self.is_parent(other): return self return self.common_parent(other.parent) @classmethod def by_name(cls, project, name): q = db.session.query(cls).filter_by(name=name) q = q.filter_by(project=project) return q.first() @classmethod def by_obj_name(cls, project, obj, name): q = db.session.query(cls) q = q.filter_by(project=project) q = q.filter_by(name=name) q = q.filter_by(obj=obj) return q.first() def to_dict_index(self): return { 'name': self.name, 'label': self.label, 'hidden': self.hidden, 'obj': self.obj, 'api_url': url_for('schemata_api.view', slug=self.project.slug, name=self.name) } def to_dict(self): data = self.to_dict_index() data['id'] = self.id data['meta'] = self.meta if self.parent is not None: data['parent'] = self.parent.to_dict_index() else: data['parent'] = None data['project'] = self.project.to_dict_short() data['attributes'] = [a.to_dict() for a in self.local_attributes] for attr in self.inherited_attributes: d = attr.to_dict() d['inherited'] = True data['attributes'].append(d) return data
class Schema(db.Model, IntBase): __tablename__ = 'grano_schema' name = db.Column(db.Unicode()) label = db.Column(db.Unicode()) hidden = db.Column(db.Boolean()) obj = db.Column(db.Unicode()) meta = db.Column(MutableDict.as_mutable(JSONEncodedDict)) attributes = db.relationship(Attribute, backref='schema', lazy='dynamic', cascade='all, delete, delete-orphan') properties = db.relationship(Property, backref='schema', lazy='dynamic', cascade='all, delete, delete-orphan') relations = db.relationship('Relation', backref='schema', lazy='dynamic', cascade='all, delete, delete-orphan') project_id = db.Column(db.Integer, db.ForeignKey('grano_project.id')) def get_attribute(self, name): for attribute in self.attributes: if attribute.name == name: return attribute @classmethod def by_name(cls, project, name): q = db.session.query(cls).filter_by(name=name) q = q.filter_by(project=project) return q.first() @classmethod def by_obj_name(cls, project, obj, name): q = db.session.query(cls) q = q.filter_by(project=project) q = q.filter_by(name=name) q = q.filter_by(obj=obj) return q.first() def to_dict_index(self): return { 'name': self.name, 'default': self.name == ENTITY_DEFAULT_SCHEMA, 'label': self.label, 'hidden': self.hidden, 'meta': self.meta, 'obj': self.obj, 'api_url': url_for('schemata_api.view', slug=self.project.slug, name=self.name) } def to_dict(self): data = self.to_dict_index() data['id'] = self.id data['project'] = self.project.to_dict_index() data['attributes'] = [a.to_dict() for a in self.attributes] return data
class Property(db.Model, IntBase): __tablename__ = 'grano_property' attribute_id = db.Column(db.Integer, db.ForeignKey('grano_attribute.id')) author_id = db.Column(db.Integer, db.ForeignKey('grano_account.id')) entity_id = db.Column(db.Unicode(), db.ForeignKey('grano_entity.id'), index=True, nullable=True) relation_id = db.Column(db.Unicode(), db.ForeignKey('grano_relation.id'), index=True, nullable=True) name = db.Column(db.Unicode(), index=True) value_string = db.Column(db.Unicode()) value_integer = db.Column(db.Integer()) value_float = db.Column(db.Float()) value_datetime = db.Column(db.DateTime()) value_datetime_precision = db.Column( db.Enum(*DATETIME_PRECISION, native_enum=False)) value_boolean = db.Column(db.Boolean()) value_file_id = db.Column(db.Integer(), db.ForeignKey('grano_file.id')) source_url = db.Column(db.Unicode()) active = db.Column(db.Boolean()) @property def value(self): # check file column first since file uses both # value_string and value_file_id if self.value_file_id is not None: return self.value_file_id for column in Attribute.DATATYPES.values(): value = getattr(self, column) if value is not None: return value @classmethod def type_column(self, value): for name, typ in VALUE_COLUMNS.items(): if isinstance(value, typ): return name return 'value_string' def to_dict_index(self): data = {'value': self.value, 'source_url': self.source_url} if self.value_file_id is not None: data['file_url'] = self.value_string elif self.value_datetime is not None: data['value_precision'] = self.value_datetime_precision return data def to_dict_kv(self): return self.name, self.to_dict_index() def to_dict(self): name, data = self.to_dict_index() data['id'] = self.id data['name'] = name data['created_at'] = self.created_at data['updated_at'] = self.updated_at data['active'] = self.active return data