Skip to content

Commit b98c2db

Browse files
committed
Merge branch 'cart-branch' of https://github.com/biocore/qiita into cart-branch
2 parents 3aa8f73 + c1fc3c8 commit b98c2db

File tree

17 files changed

+328
-57
lines changed

17 files changed

+328
-57
lines changed

qiita_db/analysis.py

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def get_by_status(cls, status):
9999
return {x[0] for x in conn_handler.execute_fetchall(sql, (status,))}
100100

101101
@classmethod
102-
def create(cls, owner, name, description, parent=None):
102+
def create(cls, owner, name, description, parent=None, from_default=False):
103103
"""Creates a new analysis on the database
104104
105105
Parameters
@@ -112,23 +112,53 @@ def create(cls, owner, name, description, parent=None):
112112
Description of the analysis
113113
parent : Analysis object, optional
114114
The analysis this one was forked from
115+
from_default : bool, optional
116+
If True, use the default analysis to populate selected samples.
117+
Default False.
115118
"""
119+
queue = "create_analysis"
116120
conn_handler = SQLConnectionHandler()
121+
conn_handler.create_queue(queue)
117122
# TODO after demo: if exists()
118-
119-
# insert analysis information into table with "in construction" status
120-
sql = ("INSERT INTO qiita.{0} (email, name, description, "
121-
"analysis_status_id) VALUES (%s, %s, %s, 1) "
122-
"RETURNING analysis_id".format(cls._table))
123-
a_id = conn_handler.execute_fetchone(
124-
sql, (owner.id, name, description))[0]
123+
# Needed since issue #292 exists
124+
status_id = conn_handler.execute_fetchone(
125+
"SELECT analysis_status_id from qiita.analysis_status WHERE "
126+
"status = 'in_construction'")[0]
127+
if from_default:
128+
# insert analysis and move samples into that new analysis
129+
dflt_id = owner.default_analysis
130+
sql = """INSERT INTO qiita.{0}
131+
(email, name, description, analysis_status_id)
132+
VALUES (%s, %s, %s, %s)
133+
RETURNING analysis_id""".format(cls._table)
134+
conn_handler.add_to_queue(queue, sql, (owner.id, name,
135+
description, status_id))
136+
# MAGIC NUMBER 3: command selection step
137+
# needed so we skip the sample selection step
138+
sql = """INSERT INTO qiita.analysis_workflow
139+
(analysis_id, step) VALUES (%s, %s)
140+
RETURNING %s"""
141+
conn_handler.add_to_queue(queue, sql, ['{0}', 3, '{0}'])
142+
sql = """UPDATE qiita.analysis_sample
143+
SET analysis_id = %s
144+
WHERE analysis_id = %s RETURNING %s"""
145+
conn_handler.add_to_queue(queue, sql, ['{0}', dflt_id, '{0}'])
146+
else:
147+
# insert analysis information into table as "in construction"
148+
sql = """INSERT INTO qiita.{0}
149+
(email, name, description, analysis_status_id)
150+
VALUES (%s, %s, %s, %s)
151+
RETURNING analysis_id""".format(cls._table)
152+
conn_handler.add_to_queue(
153+
queue, sql, (owner.id, name, description, status_id))
125154

126155
# add parent if necessary
127156
if parent:
128157
sql = ("INSERT INTO qiita.analysis_chain (parent_id, child_id) "
129-
"VALUES (%s, %s)")
130-
conn_handler.execute(sql, (parent.id, a_id))
158+
"VALUES (%s, %s) RETURNING child_id")
159+
conn_handler.add_to_queue(queue, sql, [parent.id, '{0}'])
131160

161+
a_id = conn_handler.execute_queue(queue)[0]
132162
return cls(a_id)
133163

134164
# ---- Properties ----

qiita_db/data.py

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,12 +1425,53 @@ def data_type(self, ret_id=False):
14251425
return data_type[0]
14261426

14271427
@property
1428-
def processed_date(self):
1429-
"""Return the processed date"""
1428+
def processing_info(self):
1429+
"""Return the processing item and settings used to create the data
1430+
1431+
Returns
1432+
-------
1433+
dict
1434+
Parameter settings keyed to the parameter, along with date and
1435+
algorithm used
1436+
"""
1437+
# Get processed date and the info for the dynamic table
14301438
conn_handler = SQLConnectionHandler()
1431-
return conn_handler.execute_fetchone(
1432-
"SELECT processed_date FROM qiita.{0} WHERE "
1433-
"processed_data_id=%s".format(self._table), (self.id,))[0]
1439+
sql = """SELECT processed_date, processed_params_table,
1440+
processed_params_id FROM qiita.{0}
1441+
WHERE processed_data_id=%s""".format(self._table)
1442+
static_info = conn_handler.execute_fetchone(sql, (self.id,))
1443+
1444+
# Get the info from the dynamic table, including reference used
1445+
sql = """SELECT * from qiita.{0}
1446+
JOIN qiita.reference USING (reference_id)
1447+
WHERE processed_params_id = {1}
1448+
""".format(static_info['processed_params_table'],
1449+
static_info['processed_params_id'])
1450+
dynamic_info = dict(conn_handler.execute_fetchone(sql))
1451+
1452+
# replace reference filepath_ids with full filepaths
1453+
# figure out what columns have filepaths and what don't
1454+
ref_fp_cols = {'sequence_filepath', 'taxonomy_filepath',
1455+
'tree_filepath'}
1456+
fp_ids = [str(dynamic_info[col]) for col in ref_fp_cols
1457+
if dynamic_info[col] is not None]
1458+
# Get the filepaths and create dict of fpid to filepath
1459+
sql = ("SELECT filepath_id, filepath FROM qiita.filepath WHERE "
1460+
"filepath_id IN ({})").format(','.join(fp_ids))
1461+
lookup = {fp[0]: fp[1] for fp in conn_handler.execute_fetchall(sql)}
1462+
# Loop through and replace ids
1463+
for key in ref_fp_cols:
1464+
if dynamic_info[key] is not None:
1465+
dynamic_info[key] = lookup[dynamic_info[key]]
1466+
1467+
# add missing info to the dictionary and remove id column info
1468+
dynamic_info['processed_date'] = static_info['processed_date']
1469+
dynamic_info['algorithm'] = static_info[
1470+
'processed_params_table'].split('_')[-1]
1471+
del dynamic_info['processed_params_id']
1472+
del dynamic_info['reference_id']
1473+
1474+
return dynamic_info
14341475

14351476
@property
14361477
def samples(self):

qiita_db/support_files/patches/21.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- March 28, 2015
2+
-- Add default analyses for all existing users
3+
DO $do$
4+
DECLARE
5+
eml varchar;
6+
aid bigint;
7+
BEGIN
8+
FOR eml IN
9+
SELECT email FROM qiita.qiita_user
10+
LOOP
11+
INSERT INTO qiita.analysis (email, name, description, dflt, analysis_status_id) VALUES (eml, eml || '-dflt', 'dflt', true, 1) RETURNING analysis_id INTO aid;
12+
INSERT INTO qiita.analysis_workflow (analysis_id, step) VALUES (aid, 2);
13+
END LOOP;
14+
END $do$;

qiita_db/support_files/populate_test_db.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,3 +420,9 @@ INSERT INTO qiita.collection_job (collection_id, job_id) VALUES (1, 1);
420420

421421
--share collection with shared user
422422
INSERT INTO qiita.collection_users (email, collection_id) VALUES ('shared@foo.bar', 1);
423+
424+
--add default analysis for users
425+
INSERT INTO qiita.analysis (email, name, description, dflt, analysis_status_id) VALUES ('test@foo.bar', 'test@foo.bar-dflt', 'dflt', true, 1), ('admin@foo.bar', 'admin@foo.bar-dflt', 'dflt', true, 1), ('shared@foo.bar', 'shared@foo.bar-dflt', 'dflt', true, 1), ('demo@microbio.me', 'demo@microbio.me-dflt', 'dflt', true, 1);
426+
427+
-- Attach samples to analysis
428+
INSERT INTO qiita.analysis_sample (analysis_id, processed_data_id, sample_id) VALUES (3,1,'1.SKD8.640184'), (3,1,'1.SKB7.640196'), (3,1,'1.SKM9.640192'), (3,1,'1.SKM4.640180')

qiita_db/test/test_analysis.py

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from qiita_db.job import Job
1313
from qiita_db.user import User
1414
from qiita_db.exceptions import QiitaDBStatusError
15-
from qiita_db.util import get_mountpoint
15+
from qiita_db.util import get_mountpoint, get_count
1616
from qiita_db.study import Study, StudyPerson
1717
from qiita_db.data import ProcessedData
1818
from qiita_db.metadata_template import SampleTemplate
@@ -92,36 +92,57 @@ def test_has_access_no_access(self):
9292
def test_create(self):
9393
sql = "SELECT EXTRACT(EPOCH FROM NOW())"
9494
time1 = float(self.conn_handler.execute_fetchall(sql)[0][0])
95-
95+
new_id = get_count("qiita.analysis") + 1
9696
new = Analysis.create(User("admin@foo.bar"), "newAnalysis",
9797
"A New Analysis")
98-
self.assertEqual(new.id, 3)
98+
self.assertEqual(new.id, new_id)
9999
sql = ("SELECT analysis_id, email, name, description, "
100100
"analysis_status_id, pmid, EXTRACT(EPOCH FROM timestamp) "
101-
"FROM qiita.analysis WHERE analysis_id = 3")
102-
obs = self.conn_handler.execute_fetchall(sql)
103-
self.assertEqual(obs[0][:-1], [3, 'admin@foo.bar', 'newAnalysis',
101+
"FROM qiita.analysis WHERE analysis_id = %s")
102+
obs = self.conn_handler.execute_fetchall(sql, [new_id])
103+
self.assertEqual(obs[0][:-1], [new_id, 'admin@foo.bar', 'newAnalysis',
104104
'A New Analysis', 1, None])
105105
self.assertTrue(time1 < float(obs[0][-1]))
106106

107107
def test_create_parent(self):
108108
sql = "SELECT EXTRACT(EPOCH FROM NOW())"
109109
time1 = float(self.conn_handler.execute_fetchall(sql)[0][0])
110-
110+
new_id = get_count("qiita.analysis") + 1
111111
new = Analysis.create(User("admin@foo.bar"), "newAnalysis",
112112
"A New Analysis", Analysis(1))
113-
self.assertEqual(new.id, 3)
113+
self.assertEqual(new.id, new_id)
114114
sql = ("SELECT analysis_id, email, name, description, "
115115
"analysis_status_id, pmid, EXTRACT(EPOCH FROM timestamp) "
116-
"FROM qiita.analysis WHERE analysis_id = 3")
117-
obs = self.conn_handler.execute_fetchall(sql)
118-
self.assertEqual(obs[0][:-1], [3, 'admin@foo.bar', 'newAnalysis',
116+
"FROM qiita.analysis WHERE analysis_id = %s")
117+
obs = self.conn_handler.execute_fetchall(sql, [new_id])
118+
self.assertEqual(obs[0][:-1], [new_id, 'admin@foo.bar', 'newAnalysis',
119119
'A New Analysis', 1, None])
120120
self.assertTrue(time1 < float(obs[0][-1]))
121121

122-
sql = "SELECT * FROM qiita.analysis_chain WHERE child_id = 3"
123-
obs = self.conn_handler.execute_fetchall(sql)
124-
self.assertEqual(obs, [[1, 3]])
122+
sql = "SELECT * FROM qiita.analysis_chain WHERE child_id = %s"
123+
obs = self.conn_handler.execute_fetchall(sql, [new_id])
124+
self.assertEqual(obs, [[1, new_id]])
125+
126+
def test_create_from_default(self):
127+
new_id = get_count("qiita.analysis") + 1
128+
owner = User("test@foo.bar")
129+
new = Analysis.create(owner, "newAnalysis",
130+
"A New Analysis", from_default=True)
131+
self.assertEqual(new.id, new_id)
132+
self.assertEqual(new.step, 3)
133+
134+
# Make sure samples were transfered properly
135+
sql = "SELECT * FROM qiita.analysis_sample WHERE analysis_id = %s"
136+
obs = self.conn_handler.execute_fetchall(sql, [owner.default_analysis])
137+
exp = []
138+
self.assertEqual(obs, exp)
139+
sql = "SELECT * FROM qiita.analysis_sample WHERE analysis_id = %s"
140+
obs = self.conn_handler.execute_fetchall(sql, [new_id])
141+
exp = [[new_id, 1, '1.SKD8.640184'],
142+
[new_id, 1, '1.SKB7.640196'],
143+
[new_id, 1, '1.SKM9.640192'],
144+
[new_id, 1, '1.SKM4.640180']]
145+
self.assertEqual(obs, exp)
125146

126147
def test_retrieve_owner(self):
127148
self.assertEqual(self.analysis.owner, "test@foo.bar")
@@ -242,21 +263,23 @@ def test_retrieve_biom_tables_none(self):
242263
self.assertEqual(new.biom_tables, None)
243264

244265
def test_set_step(self):
266+
new_id = get_count("qiita.analysis") + 1
245267
new = Analysis.create(User("admin@foo.bar"), "newAnalysis",
246268
"A New Analysis", Analysis(1))
247269
new.step = 2
248-
sql = "SELECT * FROM qiita.analysis_workflow WHERE analysis_id = 3"
249-
obs = self.conn_handler.execute_fetchall(sql)
250-
self.assertEqual(obs, [[3, 2]])
270+
sql = "SELECT * FROM qiita.analysis_workflow WHERE analysis_id = %s"
271+
obs = self.conn_handler.execute_fetchall(sql, [new_id])
272+
self.assertEqual(obs, [[new_id, 2]])
251273

252274
def test_set_step_twice(self):
275+
new_id = get_count("qiita.analysis") + 1
253276
new = Analysis.create(User("admin@foo.bar"), "newAnalysis",
254277
"A New Analysis", Analysis(1))
255278
new.step = 2
256279
new.step = 4
257-
sql = "SELECT * FROM qiita.analysis_workflow WHERE analysis_id = 3"
258-
obs = self.conn_handler.execute_fetchall(sql)
259-
self.assertEqual(obs, [[3, 4]])
280+
sql = "SELECT * FROM qiita.analysis_workflow WHERE analysis_id = %s"
281+
obs = self.conn_handler.execute_fetchall(sql, [new_id])
282+
self.assertEqual(obs, [[new_id, 4]])
260283

261284
def test_retrieve_step(self):
262285
new = Analysis.create(User("admin@foo.bar"), "newAnalysis",

qiita_db/test/test_data.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -993,9 +993,20 @@ def test_link_filepaths_status_setter(self):
993993
pd._set_link_filepaths_status('failed: error')
994994
self.assertEqual(pd.link_filepaths_status, 'failed: error')
995995

996-
def test_processed_date(self):
996+
def test_processing_info(self):
997997
pd = ProcessedData(1)
998-
self.assertEqual(pd.processed_date, datetime(2012, 10, 1, 9, 30, 27))
998+
exp = {
999+
'algorithm': 'uclust',
1000+
'processed_date': datetime(2012, 10, 1, 9, 30, 27),
1001+
'enable_rev_strand_match': True,
1002+
'similarity': 0.97,
1003+
'suppress_new_clusters': True,
1004+
'reference_name': 'Greengenes',
1005+
'reference_version': '13_8',
1006+
'sequence_filepath': 'GreenGenes_13_8_97_otus.fasta',
1007+
'taxonomy_filepath': 'GreenGenes_13_8_97_otu_taxonomy.txt',
1008+
'tree_filepath': 'GreenGenes_13_8_97_otus.tree'}
1009+
self.assertEqual(pd.processing_info, exp)
9991010

10001011
def test_samples(self):
10011012
pd = ProcessedData(1)

qiita_db/test/test_job.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from qiita_core.util import qiita_test_checker
1616
from qiita_db.job import Job, Command
1717
from qiita_db.user import User
18-
from qiita_db.util import get_mountpoint
18+
from qiita_db.util import get_mountpoint, get_count
1919
from qiita_db.analysis import Analysis
2020
from qiita_db.exceptions import (QiitaDBDuplicateError, QiitaDBStatusError,
2121
QiitaDBUnknownIDError)
@@ -219,16 +219,17 @@ def test_create_exists(self):
219219

220220
def test_create_exists_return_existing(self):
221221
"""Makes sure creation doesn't duplicate a job by returning existing"""
222+
new_id = get_count("qiita.analysis") + 1
222223
Analysis.create(User("demo@microbio.me"), "new", "desc")
223224
self.conn_handler.execute(
224225
"INSERT INTO qiita.analysis_sample "
225226
"(analysis_id, processed_data_id, sample_id) VALUES "
226-
"(3, 1, '1.SKB8.640193'), (3, 1, '1.SKD8.640184'), "
227-
"(3, 1, '1.SKB7.640196'), (3, 1, '1.SKM9.640192'), "
228-
"(3, 1, '1.SKM4.640180')")
227+
"({0}, 1, '1.SKB8.640193'), ({0}, 1, '1.SKD8.640184'), "
228+
"({0}, 1, '1.SKB7.640196'), ({0}, 1, '1.SKM9.640192'), "
229+
"({0}, 1, '1.SKM4.640180')".format(new_id))
229230
new = Job.create("18S", "Beta Diversity",
230231
{"--otu_table_fp": 1, "--mapping_fp": 1},
231-
Analysis(3), return_existing=True)
232+
Analysis(new_id), return_existing=True)
232233
self.assertEqual(new.id, 2)
233234

234235
def test_retrieve_datatype(self):

qiita_db/test/test_setup.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88

99
from unittest import TestCase, main
1010

11-
from qiita_core.util import qiita_test_checker
1211
from qiita_db.util import get_count, check_count
1312

1413

15-
@qiita_test_checker()
1614
class SetupTest(TestCase):
1715
"""Tests that the test database have been successfully populated"""
1816

@@ -111,7 +109,7 @@ def test_job(self):
111109
self.assertEqual(get_count("qiita.job"), 3)
112110

113111
def test_analysis(self):
114-
self.assertEqual(get_count("qiita.analysis"), 2)
112+
self.assertEqual(get_count("qiita.analysis"), 6)
115113

116114
def test_analysis_job(self):
117115
self.assertEqual(get_count("qiita.analysis_job"), 3)
@@ -123,7 +121,7 @@ def test_analysis_filepath(self):
123121
self.assertEqual(get_count("qiita.analysis_filepath"), 2)
124122

125123
def test_analysis_sample(self):
126-
self.assertEqual(get_count("qiita.analysis_sample"), 9)
124+
self.assertEqual(get_count("qiita.analysis_sample"), 13)
127125

128126
def test_analysis_users(self):
129127
self.assertEqual(get_count("qiita.analysis_users"), 1)

qiita_db/test/test_user.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ def test_create_user(self):
109109
'email': 'new@test.bar'}
110110
self._check_correct_info(obs, exp)
111111

112+
# make sure default analysis created
113+
sql = ("SELECT email, name, description, dflt FROM qiita.analysis "
114+
"WHERE email = 'new@test.bar'")
115+
obs = self.conn_handler.execute_fetchall(sql)
116+
exp = [['new@test.bar', 'new@test.bar-dflt', 'dflt', True]]
117+
self.assertEqual(obs, exp)
118+
112119
def test_create_user_info(self):
113120
user = User.create('new@test.bar', 'password', self.userinfo)
114121
self.assertEqual(user.id, 'new@test.bar')
@@ -212,6 +219,10 @@ def test_set_info_bad_info(self):
212219
with self.assertRaises(QiitaDBColumnError):
213220
self.user.info = self.userinfo
214221

222+
def test_default_analysis(self):
223+
obs = self.user.default_analysis
224+
self.assertEqual(obs, 4)
225+
215226
def test_get_user_studies(self):
216227
user = User('test@foo.bar')
217228
self.assertEqual(user.user_studies, {1})

0 commit comments

Comments
 (0)