diff --git a/qiita_db/study.py b/qiita_db/study.py index 03e6ef607..ef21feddc 100644 --- a/qiita_db/study.py +++ b/qiita_db/study.py @@ -464,6 +464,42 @@ def delete(cls, id_): qdb.sql_connection.TRN.execute() + @classmethod + def get_tags(cls): + """Returns the available study tags + + Returns + ------- + list of DictCursor + Table-like structure of metadata, one tag per row. Can be + accessed as a list of dictionaries, keyed on column name. + """ + with qdb.sql_connection.TRN: + sql = """SELECT study_tag_id, study_tag + FROM qiita.study_tags""" + + qdb.sql_connection.TRN.add(sql) + return qdb.sql_connection.TRN.execute_fetchindex() + + @classmethod + def insert_tags(cls, user, tags): + """Insert available study tags + + Parameters + ---------- + user : qiita_db.user.User + The user adding the tags + tags : list of str + The list of tags to add + """ + with qdb.sql_connection.TRN: + sql = """INSERT INTO qiita.study_tags (email, study_tag) + VALUES (%s, %s)""" + sql_args = [[user.email, tag] for tag in tags] + + qdb.sql_connection.TRN.add(sql, sql_args, many=True) + qdb.sql_connection.TRN.execute() + # --- Attributes --- @property @@ -921,7 +957,52 @@ def ebi_submission_status(self, value): ebi_submission_status.__doc__.format(', '.join(_VALID_EBI_STATUS)) - # --- methods --- + @property + def tags(self): + """Returns the tags of the study + + Returns + ------- + list of str + The study tags + """ + with qdb.sql_connection.TRN: + sql = """SELECT study_tag_id, study_tag + FROM qiita.study_tags + LEFT JOIN qiita.per_study_tags USING (study_tag_id) + WHERE study_id = {0}""".format(self._id) + qdb.sql_connection.TRN.add(sql) + return qdb.sql_connection.TRN.execute_fetchindex() + + @tags.setter + def tags(self, tag_ids): + """Sets the tags of the study + + Parameters + ---------- + tag_ids : list of int + The tag ids of the study + """ + with qdb.sql_connection.TRN: + sql = """DELETE FROM qiita.per_study_tags WHERE study_id = %s""" + qdb.sql_connection.TRN.add(sql, [self._id]) + + if tag_ids: + sql = """INSERT INTO qiita.per_study_tags + (study_tag_id, study_id) + SELECT %s, %s + WHERE + NOT EXISTS ( + SELECT study_tag_id, study_id + FROM qiita.per_study_tags + WHERE study_tag_id = %s AND study_id = %s + )""" + sql_args = [[tid, self._id, tid, self._id] for tid in tag_ids] + qdb.sql_connection.TRN.add(sql, sql_args, many=True) + + qdb.sql_connection.TRN.execute() + +# --- methods --- def artifacts(self, dtype=None, artifact_type=None): """Returns the list of artifacts associated with the study diff --git a/qiita_db/support_files/patches/50.sql b/qiita_db/support_files/patches/50.sql new file mode 100644 index 000000000..f732ef7b5 --- /dev/null +++ b/qiita_db/support_files/patches/50.sql @@ -0,0 +1,19 @@ +-- Feb 3, 2017 +-- adding study tagging system + +CREATE TABLE qiita.study_tags ( + study_tag_id bigserial NOT NULL, + email varchar NOT NULL, + study_tag varchar NOT NULL, + CONSTRAINT pk_study_tag UNIQUE ( study_tag ), + CONSTRAINT pk_study_tag_id PRIMARY KEY ( study_tag_id ) +) ; + +CREATE INDEX idx_study_tag_id ON qiita.study_tags ( study_tag_id ) ; +ALTER TABLE qiita.study_tags ADD CONSTRAINT fk_study_tags FOREIGN KEY ( email ) REFERENCES qiita.qiita_user( email ); + +CREATE TABLE qiita.per_study_tags ( + study_tag_id bigint NOT NULL, + study_id bigint NOT NULL, + CONSTRAINT pk_per_study_tags PRIMARY KEY ( study_tag_id, study_id ) +) ; diff --git a/qiita_db/support_files/qiita-db.dbs b/qiita_db/support_files/qiita-db.dbs index 889d80d87..1f7ebe2f5 100644 --- a/qiita_db/support_files/qiita-db.dbs +++ b/qiita_db/support_files/qiita-db.dbs @@ -1120,6 +1120,26 @@ + + + + + + + + + + + + + + + + + + + +
What portals are available to show a study in @@ -1748,6 +1768,23 @@ Controlled Vocabulary]]>
+ + + + + + + + + + + + + + + + +
Links shared studies to users they are shared with @@ -1841,97 +1878,99 @@ Controlled Vocabulary]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + analysis tables diff --git a/qiita_db/support_files/qiita-db.html b/qiita_db/support_files/qiita-db.html index 5ec6aeb0c..5c7f9311b 100644 --- a/qiita_db/support_files/qiita-db.html +++ b/qiita_db/support_files/qiita-db.html @@ -97,7 +97,7 @@ - +
- - + - - - - - - - - - - - - - + - + - - - - - - - - - - - - - + - + - - - - - - + + @@ -4546,35 +4558,47 @@

Table study_person
Contact information for the various people involved in a study
Table environmental_package
*study_person_id bigserial
*name varchar
*emailenvironmental_package_name varchar The name of the environmental package
*affiliation varchar The institution with which this person is affiliated
 address varchar( 100 )
 phonemetadata_table varchar Contains the name of the table that contains the pre-defined metadata columns for the environmental package
Indexes
Pkpk_study_person ON study_person_id
Uidx_study_person ON name, affiliation
Pkpk_environmental_package ON environmental_package_name
- - + + - - + + - + + + + + + + + + + + + + - - + + - - + + - - + + @@ -4583,44 +4607,44 @@

Table study_experimental_factor
EFO ontological link of experimental factors to studies
Table investigation
Overarching investigation information.An investigation comprises one or more individual studies.
*study_id bigint investigation_id bigserial
*efo_idinvestigation_name varchar
*investigation_description varchar Describes the overarching goal of the investigation
 contact_person_id bigint
Indexes
Pkidx_study_experimental_factor ON study_id, efo_id
Pkpk_investigation ON investigation_id
 idx_study_experimental_factor_0 ON study_id
 idx_investigation ON contact_person_id
Foreign Keys
 fk_study_experimental_factor ( study_id ) ref study (study_id)  fk_investigation_study_person ( contact_person_id ) ref study_person (study_person_id)
- - + + - + - - + + - - + + - + - - + + - + - - + + @@ -4629,24 +4653,28 @@

Table study_environmental_package
Holds the 1 to many relationship between the study and the environmental_package
Table study_portal
Controls what studies are visible on what portals
*study_idstudy_id bigint
*environmental_package_name varchar portal_type_id bigint
Indexes
Pkpk_study_environmental_package ON study_id, environmental_package_name
Pkpk_study_portal ON study_id, portal_type_id
 idx_study_environmental_package
 idx_study_portal ON study_id
 idx_study_environmental_package_0 ON environmental_package_name
 idx_study_portal_0 ON portal_type_id
Foreign Keys
 fk_study_environmental_package fk_study_portal ( study_id ) ref study (study_id)
 fk_study_environmental_package_0 ( environmental_package_name ) ref environmental_package (environmental_package_name)  fk_study_portal_0 ( portal_type_id ) ref portal_type (portal_type_id)
- + - - - + + + - + - + - - + + + + + + @@ -4655,43 +4683,43 @@

Table environmental_package
Table data_type
*environmental_package_name varchar The name of the environmental package data_type_id bigserial
*metadata_tabledata_type varchar Contains the name of the table that contains the pre-defined metadata columns for the environmental package Data type (16S, metabolome, etc) the job will use
Indexes
Pkpk_environmental_package ON environmental_package_name
Pkpk_data_type ON data_type_id
Uidx_data_type ON data_type
- + - + - - + + - - + + - - + + - - + + - - + + - - + + @@ -4700,196 +4728,26 @@

Table investigation_study
Table software_publication
*investigation_idsoftware_id bigint
*study_id bigint publication_doi varchar
Indexes
Pkidx_investigation_study ON investigation_id, study_id
 idx_software_publication ON software_id
 idx_investigation_study_investigation ON investigation_id
 idx_software_publication ON publication_doi
 idx_investigation_study_study ON study_id
Pkidx_software_publication_0 ON software_id, publication_doi
Foreign Keys
 fk_investigation_study ( investigation_id ) ref investigation (investigation_id)  fk_software_publication ( software_id ) ref software (software_id)
 fk_investigation_study_study ( study_id ) ref study (study_id)  fk_software_publication_0 ( publication_doi ) ref publication (doi)
- - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - -
Table investigation
Overarching investigation information.An investigation comprises one or more individual studies.
Table visibility
*investigation_idvisibility_id bigserial
*investigation_namevisibility varchar
*investigation_descriptionvisibility_description varchar Describes the overarching goal of the investigation
 contact_person_id bigint
Indexes
Pkpk_investigation ON investigation_id
 idx_investigation ON contact_person_id
Foreign Keys
 fk_investigation_study_person ( contact_person_id ) ref study_person (study_person_id)
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table study_portal
Controls what studies are visible on what portals
*study_id bigint
*portal_type_id bigint
Indexes
Pkpk_study_portal ON study_id, portal_type_id
 idx_study_portal ON study_id
 idx_study_portal_0 ON portal_type_id
Foreign Keys
 fk_study_portal ( study_id ) ref study (study_id)
 fk_study_portal_0 ( portal_type_id ) ref portal_type (portal_type_id)
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table data_type
*data_type_id bigserial
*data_type varchar Data type (16S, metabolome, etc) the job will use
Indexes
Pkpk_data_type ON data_type_id
Uidx_data_type ON data_type
- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table software_publication
*software_id bigint
*publication_doi varchar
Indexes
 idx_software_publication ON software_id
 idx_software_publication ON publication_doi
Pkidx_software_publication_0 ON software_id, publication_doi
Foreign Keys
 fk_software_publication ( software_id ) ref software (software_id)
 fk_software_publication_0 ( publication_doi ) ref publication (doi)
- -

- - - - - - - - - - - - - - - - - - - - - - + @@ -4978,42 +4836,6 @@
Table visibility
*visibility_id bigserial
*visibility varchar
*visibility_description varchar
Indexes
Pkpk_visibility
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table timeseries_type
*timeseries_type_id bigserial
*timeseries_type varchar
*intervention_type varchar DEFO 'None'
Indexes
Pkpk_timeseries_type ON timeseries_type_id
Uidx_timeseries_type ON timeseries_type, intervention_type
-

@@ -6947,4 +6769,314 @@
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table study_environmental_package
Holds the 1 to many relationship between the study and the environmental_package
*study_id bigint
*environmental_package_name varchar
Indexes
Pkpk_study_environmental_package ON study_id, environmental_package_name
 idx_study_environmental_package ON study_id
 idx_study_environmental_package_0 ON environmental_package_name
Foreign Keys
 fk_study_environmental_package ( study_id ) ref study (study_id)
 fk_study_environmental_package_0 ( environmental_package_name ) ref environmental_package (environmental_package_name)
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table study_person
Contact information for the various people involved in a study
*study_person_id bigserial
*name varchar
*email varchar
*affiliation varchar The institution with which this person is affiliated
 address varchar( 100 )
 phone varchar
Indexes
Pkpk_study_person ON study_person_id
Uidx_study_person ON name, affiliation
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table investigation_study
*investigation_id bigint
*study_id bigint
Indexes
Pkidx_investigation_study ON investigation_id, study_id
 idx_investigation_study_investigation ON investigation_id
 idx_investigation_study_study ON study_id
Foreign Keys
 fk_investigation_study ( investigation_id ) ref investigation (investigation_id)
 fk_investigation_study_study ( study_id ) ref study (study_id)
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table per_study_tags
*study_tag_id bigint
*study_id integer
Indexes
Pkpk_per_study_tags ON study_tag_id, study_id
 idx_per_study_tags ON study_id
 idx_per_study_tags ON study_tag_id
Foreign Keys
 fk_per_study_tags_study ( study_id ) ref study (study_id)
 fk_per_study_tags_study_tags ( study_tag_id ) ref study_tags (study_tag_id)
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table study_experimental_factor
EFO ontological link of experimental factors to studies
*study_id bigint
*efo_id bigint
Indexes
Pkidx_study_experimental_factor ON study_id, efo_id
 idx_study_experimental_factor_0 ON study_id
Foreign Keys
 fk_study_experimental_factor ( study_id ) ref study (study_id)
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table timeseries_type
*timeseries_type_id bigserial
*timeseries_type varchar
*intervention_type varchar DEFO 'None'
Indexes
Pkpk_timeseries_type ON timeseries_type_id
Uidx_timeseries_type ON timeseries_type, intervention_type
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table study_tags
*study_tag_id bigserial
*study_tag varchar
*email varchar
Indexes
Pkpk_study_tags ON study_tag_id
Uidx_study_tags ON study_tag
 idx_study_tags ON email
Foreign Keys
 fk_study_tags_qiita_user ( email ) ref qiita_user (email)
+ \ No newline at end of file diff --git a/qiita_db/test/test_study.py b/qiita_db/test/test_study.py index 5f2cbcd66..2ccf23c67 100644 --- a/qiita_db/test/test_study.py +++ b/qiita_db/test/test_study.py @@ -832,6 +832,33 @@ def test_environmental_packages_sandboxed(self): with self.assertRaises(qdb.exceptions.QiitaDBStatusError): self.study.environmental_packages = ['air'] + def test_study_tags(self): + # inserting new tags + user = qdb.user.User('test@foo.bar') + tags = ['this is my tag', 'I want GOLD!!'] + qdb.study.Study.insert_tags(user, tags) + + # testing that insertion went fine + obs = qdb.study.Study.get_tags() + exp = [[i + 1, tag] for i, tag in enumerate(tags)] + self.assertEqual(obs, exp) + + # assigning the tags to study + study = qdb.study.Study(1) + self.assertEqual(study.tags, []) + study.tags = [tig for tig, tag in obs] + # and checking that everything went fine + self.assertEqual(obs, study.tags) + + # making sure that everything is overwritten + obs.pop() + study.tags = [tig for tig, tag in obs] + self.assertEqual(obs, study.tags) + + # cleaning tags + study.tags = [] + self.assertEqual(study.tags, []) + if __name__ == "__main__": main()