-
Notifications
You must be signed in to change notification settings - Fork 37
/
ontology_annotation.py
87 lines (73 loc) · 4.05 KB
/
ontology_annotation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
from sqlalchemy import Column, String, ForeignKey, Integer
from sqlalchemy.orm import relationship
from isatools.model import OntologyAnnotation as OntologyAnnotationModel
from isatools.database.models.relationships import (
study_design_descriptors,
study_characteristic_categories,
study_unit_categories,
person_roles,
assay_unit_categories, assay_characteristic_categories
)
from isatools.database.utils import Base
from isatools.database.models.utils import make_get_table_method
class OntologyAnnotation(Base):
""" The SQLAlchemy model for the OntologyAnnotation table """
__tablename__: str = 'ontology_annotation'
ontology_annotation_id: str = Column(String, primary_key=True)
annotation_value: str = Column(String)
term_accession: str = Column(String)
# Relationships back-ref
design_descriptors: relationship = relationship(
'Study', secondary=study_design_descriptors, back_populates='study_design_descriptors')
characteristic_categories: relationship = relationship(
'Study', secondary=study_characteristic_categories, back_populates='characteristic_categories')
unit_categories: relationship = relationship(
'Study', secondary=study_unit_categories, back_populates='unit_categories')
roles: relationship = relationship('Person', secondary=person_roles, back_populates='roles')
assays_units: relationship = relationship(
'Assay', secondary=assay_unit_categories, back_populates='unit_categories')
assays_characteristics: relationship = relationship(
'Assay', secondary=assay_characteristic_categories, back_populates='characteristic_categories')
# Relationships many-to-one
term_source_id: str = Column(String, ForeignKey('ontology_source.ontology_source_id'))
term_source: relationship = relationship('OntologySource', backref='ontology_annotations')
# References: one-to-many
comments: relationship = relationship('Comment', back_populates='ontology_annotation')
def to_json(self):
""" Convert the SQLAlchemy object to a dictionary
:return: The dictionary representation of the object taken from the database
"""
return {
"@id": self.ontology_annotation_id,
'annotationValue': self.annotation_value,
'termSource': self.term_source_id if self.term_source_id else None,
'termAccession': self.term_accession,
'comments': [c.to_json() for c in self.comments]
}
def make_ontology_annotation_methods() -> None:
""" This function will dynamically add the methods to the OntologyAnnotation class that are required to interact
with the database. This is done to avoid circular imports and to extra dependencies in the models package.
It's called in the init of the database models package.
"""
def to_sql(self, session):
""" Convert the OntologyAnnotation object to a SQLAlchemy object and adds it to the session. If the object
already exists in the database session, it will be returned instead. This is done to avoid duplicates.
:param self: the OntologyAnnotation object. Will be injected automatically.
:param session: The SQLAlchemy session to use.
:return: The SQLAlchemy object ready to be committed to the database session.
"""
oa = session.query(OntologyAnnotation).get(self.id)
if oa:
return oa
term_source_id = self.term_source.to_sql(session) if self.term_source else None
oa = OntologyAnnotation(
ontology_annotation_id=self.id,
annotation_value=self.term,
term_accession=self.term_accession,
term_source_id=term_source_id.ontology_source_id if term_source_id else None,
comments=[comment.to_sql() for comment in self.comments]
)
session.add(oa)
return oa
setattr(OntologyAnnotationModel, 'to_sql', to_sql)
setattr(OntologyAnnotationModel, 'get_table', make_get_table_method(OntologyAnnotation))