Skip to content

Commit e2f52c7

Browse files
committed
Fixing merge conflicts
2 parents 77afb1c + adff033 commit e2f52c7

File tree

9 files changed

+245
-86
lines changed

9 files changed

+245
-86
lines changed

qiita_db/data.py

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class BaseData(QiitaObject):
103103
--------
104104
RawData
105105
PreprocessedData
106-
PreprocessedData
106+
ProcessedData
107107
"""
108108
_filepath_table = "filepath"
109109

@@ -807,6 +807,73 @@ def create(cls, study, preprocessed_params_table, preprocessed_params_id,
807807
ppd.add_filepaths(filepaths, conn_handler)
808808
return ppd
809809

810+
@classmethod
811+
def delete(cls, ppd_id):
812+
"""Removes the preprocessed data with id ppd_id
813+
814+
Parameters
815+
----------
816+
ppd_id : int
817+
The preprocessed data id
818+
819+
Raises
820+
------
821+
QiitaDBStatusError
822+
If the preprocessed data status is not sandbox or if the
823+
preprocessed data EBI and VAMPS submission is not in a valid state
824+
['not submitted', 'failed']
825+
QiitaDBError
826+
If the preprocessed data has been processed
827+
"""
828+
valid_submission_states = ['not submitted', 'failed']
829+
ppd = cls(ppd_id)
830+
if ppd.status != 'sandbox':
831+
raise QiitaDBStatusError(
832+
"Illegal operation on non sandboxed preprocessed data")
833+
elif ppd.submitted_to_vamps_status() not in valid_submission_states:
834+
raise QiitaDBStatusError(
835+
"Illegal operation. This preprocessed data has or is being "
836+
"added to VAMPS.")
837+
elif ppd.submitted_to_insdc_status() not in valid_submission_states:
838+
raise QiitaDBStatusError(
839+
"Illegal operation. This preprocessed data has or is being "
840+
"added to EBI.")
841+
842+
conn_handler = SQLConnectionHandler()
843+
844+
processed_data = [str(n[0]) for n in conn_handler.execute_fetchall(
845+
"SELECT processed_data_id FROM qiita.preprocessed_processed_data "
846+
"WHERE preprocessed_data_id = {0} ORDER BY "
847+
"processed_data_id".format(ppd_id))]
848+
849+
if processed_data:
850+
raise QiitaDBError(
851+
"Preprocessed data %d cannot be removed because it was used "
852+
"to generate the following processed data: %s" % (
853+
ppd_id, ', '.join(processed_data)))
854+
855+
# delete
856+
queue = "delete_preprocessed_data_%d" % ppd_id
857+
conn_handler.create_queue(queue)
858+
859+
sql = ("DELETE FROM qiita.prep_template_preprocessed_data WHERE "
860+
"preprocessed_data_id = {0}".format(ppd_id))
861+
conn_handler.add_to_queue(queue, sql)
862+
863+
sql = ("DELETE FROM qiita.preprocessed_filepath WHERE "
864+
"preprocessed_data_id = {0}".format(ppd_id))
865+
conn_handler.add_to_queue(queue, sql)
866+
867+
sql = ("DELETE FROM qiita.study_preprocessed_data WHERE "
868+
"preprocessed_data_id = {0}".format(ppd_id))
869+
conn_handler.add_to_queue(queue, sql)
870+
871+
sql = ("DELETE FROM qiita.preprocessed_data WHERE "
872+
"preprocessed_data_id = {0}".format(ppd_id))
873+
conn_handler.add_to_queue(queue, sql)
874+
875+
conn_handler.execute_queue(queue)
876+
810877
@property
811878
def processed_data(self):
812879
r"""The processed data list generated from this preprocessed data"""
@@ -1275,7 +1342,7 @@ def delete(cls, processed_data_id):
12751342
"""
12761343
if cls(processed_data_id).status != 'sandbox':
12771344
raise QiitaDBStatusError(
1278-
"Illegal operation on non sandbox processed data")
1345+
"Illegal operation on non sandboxed processed data")
12791346

12801347
conn_handler = SQLConnectionHandler()
12811348

qiita_db/metadata_template/base_metadata_template.py

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
from skbio.util import find_duplicates
4646

4747
from qiita_core.exceptions import IncompetentQiitaDeveloperError
48+
4849
from qiita_db.exceptions import (QiitaDBUnknownIDError, QiitaDBColumnError,
4950
QiitaDBNotImplementedError,
5051
QiitaDBDuplicateHeaderError)
@@ -312,17 +313,81 @@ def handler(x):
312313
" in template %d" %
313314
(key, self._id, self._md_template.id))
314315

315-
def __setitem__(self, key, value):
316-
r"""Sets the metadata value for the category `key`
316+
def __setitem__(self, column, value):
317+
r"""Sets the metadata value for the category `column`
317318
318319
Parameters
319320
----------
320-
key : str
321-
The metadata category
322-
value : obj
323-
The new value for the category
321+
column : str
322+
The column to update
323+
value : str
324+
The value to set. This is expected to be a str on the assumption
325+
that psycopg2 will cast as necessary when updating.
326+
327+
Raises
328+
------
329+
QiitaDBColumnError
330+
If the column does not exist in the table
331+
ValueError
332+
If the value type does not match the one in the DB
324333
"""
325-
raise QiitaDBNotImplementedError()
334+
conn_handler = SQLConnectionHandler()
335+
336+
# try dynamic tables
337+
sql = """SELECT EXISTS (
338+
SELECT column_name
339+
FROM information_schema.columns
340+
WHERE table_name=%s
341+
AND table_schema='qiita'
342+
AND column_name=%s)"""
343+
exists_dynamic = conn_handler.execute_fetchone(
344+
sql, (self._dynamic_table, column))[0]
345+
# try required_sample_info
346+
sql = """SELECT EXISTS (
347+
SELECT column_name
348+
FROM information_schema.columns
349+
WHERE table_name=%s
350+
AND table_schema='qiita'
351+
AND column_name=%s)"""
352+
exists_required = conn_handler.execute_fetchone(
353+
sql, (self._table, column))[0]
354+
355+
if exists_dynamic:
356+
sql = """UPDATE qiita.{0}
357+
SET {1}=%s
358+
WHERE sample_id=%s""".format(self._dynamic_table,
359+
column)
360+
elif exists_required:
361+
# here is not required the type check as the required fields have
362+
# an explicit type check
363+
sql = """UPDATE qiita.{0}
364+
SET {1}=%s
365+
WHERE sample_id=%s""".format(self._table, column)
366+
else:
367+
raise QiitaDBColumnError("Column %s does not exist in %s" %
368+
(column, self._dynamic_table))
369+
370+
try:
371+
conn_handler.execute(sql, (value, self._id))
372+
except Exception as e:
373+
# catching error so we can check if the error is due to different
374+
# column type or something else
375+
column_type = conn_handler.execute_fetchone(
376+
"""SELECT data_type
377+
FROM information_schema.columns
378+
WHERE column_name=%s AND table_schema='qiita'
379+
""", (column,))[0]
380+
value_type = type(value).__name__
381+
382+
if column_type != value_type:
383+
raise ValueError(
384+
'The new value being added to column: "{0}" is "{1}" '
385+
'(type: "{2}"). However, this column in the DB is of '
386+
'type "{3}". Please change the value in your updated '
387+
'template or reprocess your sample template.'.format(
388+
column, value, value_type, column_type))
389+
else:
390+
raise e
326391

327392
def __delitem__(self, key):
328393
r"""Removes the sample with sample id `key` from the database

qiita_db/metadata_template/sample_template.py

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -59,80 +59,6 @@ def _check_template_class(self, md_template):
5959
if not isinstance(md_template, SampleTemplate):
6060
raise IncompetentQiitaDeveloperError()
6161

62-
def __setitem__(self, column, value):
63-
r"""Sets the metadata value for the category `column`
64-
65-
Parameters
66-
----------
67-
column : str
68-
The column to update
69-
value : str
70-
The value to set. This is expected to be a str on the assumption
71-
that psycopg2 will cast as necessary when updating.
72-
73-
Raises
74-
------
75-
QiitaDBColumnError
76-
If the column does not exist in the table
77-
"""
78-
conn_handler = SQLConnectionHandler()
79-
80-
# try dynamic tables
81-
exists_dynamic = conn_handler.execute_fetchone("""
82-
SELECT EXISTS (
83-
SELECT column_name
84-
FROM information_schema.columns
85-
WHERE table_name='{0}'
86-
AND table_schema='qiita'
87-
AND column_name='{1}')""".format(self._dynamic_table,
88-
column))[0]
89-
# try required_sample_info
90-
exists_required = conn_handler.execute_fetchone("""
91-
SELECT EXISTS (
92-
SELECT column_name
93-
FROM information_schema.columns
94-
WHERE table_name='required_sample_info'
95-
AND table_schema='qiita'
96-
AND column_name='{0}')""".format(column))[0]
97-
98-
if exists_dynamic:
99-
# catching error so we can check if the error is due to different
100-
# column type or something else
101-
try:
102-
conn_handler.execute("""
103-
UPDATE qiita.{0}
104-
SET {1}=%s
105-
WHERE sample_id=%s""".format(self._dynamic_table,
106-
column), (value, self._id))
107-
except Exception as e:
108-
column_type = conn_handler.execute_fetchone("""
109-
SELECT data_type
110-
FROM information_schema.columns
111-
WHERE column_name=%s AND table_schema='qiita'
112-
""", (column,))[0]
113-
value_type = type(value).__name__
114-
115-
if column_type != value_type:
116-
raise ValueError(
117-
'The new value being added to column: "{0}" is "{1}" '
118-
'(type: "{2}"). However, this column in the DB is of '
119-
'type "{3}". Please change the value in your updated '
120-
'template or reprocess your sample template.'.format(
121-
column, value, value_type, column_type))
122-
else:
123-
raise e
124-
elif exists_required:
125-
# here is not required the type check as the required fields have
126-
# an explicit type check
127-
conn_handler.execute("""
128-
UPDATE qiita.required_sample_info
129-
SET {0}=%s
130-
WHERE sample_id=%s
131-
""".format(column), (value, self._id))
132-
else:
133-
raise QiitaDBColumnError("Column %s does not exist in %s" %
134-
(column, self._dynamic_table))
135-
13662

13763
class SampleTemplate(MetadataTemplate):
13864
r"""Represent the SampleTemplate of a study. Provides access to the

qiita_db/metadata_template/test/test_prep_template.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,15 @@ def test_get_none(self):
220220
class TestPrepSampleReadWrite(BaseTestPrepSample):
221221
"""Tests the PrepSample class"""
222222
def test_setitem(self):
223-
"""setitem raises an error (currently not allowed)"""
224-
with self.assertRaises(QiitaDBNotImplementedError):
225-
self.tester['barcodesequence'] = 'GTCCGCAAGTTA'
223+
with self.assertRaises(QiitaDBColumnError):
224+
self.tester['column that does not exist'] = 0.3
225+
226+
with self.assertRaises(ValueError):
227+
self.tester['emp_status_id'] = "Error!"
228+
229+
self.assertEqual(self.tester['center_name'], 'ANL')
230+
self.tester['center_name'] = "FOO"
231+
self.assertEqual(self.tester['center_name'], "FOO")
226232

227233
def test_delitem(self):
228234
"""delitem raises an error (currently not allowed)"""

qiita_db/metadata_template/test/test_sample_template.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ class TestSampleReadWrite(BaseTestSample):
209209
def test_setitem(self):
210210
with self.assertRaises(QiitaDBColumnError):
211211
self.tester['column that does not exist'] = 0.30
212+
213+
with self.assertRaises(ValueError):
214+
self.tester['collection_timestamp'] = "Error!"
215+
212216
self.assertEqual(self.tester['tot_nitro'], 1.41)
213217
self.tester['tot_nitro'] = '1234.5'
214218
self.assertEqual(self.tester['tot_nitro'], 1234.5)

qiita_db/test/test_data.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,48 @@ def test_create_data_type_only(self):
478478
# preprocessed_data_id, filepath_id
479479
self.assertEqual(obs, [[3, obs_id - 1], [3, obs_id]])
480480

481+
def test_delete_basic(self):
482+
"""Correctly deletes a preprocessed data"""
483+
# testing regular delete
484+
ppd = PreprocessedData.create(
485+
self.study, self.params_table,
486+
self.params_id, self.filepaths, prep_template=self.prep_template,
487+
ebi_submission_accession=self.ebi_submission_accession,
488+
ebi_study_accession=self.ebi_study_accession)
489+
PreprocessedData.delete(ppd.id)
490+
491+
# testing that the deleted preprocessed data can't be instantiated
492+
with self.assertRaises(QiitaDBUnknownIDError):
493+
PreprocessedData(ppd.id)
494+
# and for completeness testing that it raises an error if ID
495+
# doesn't exist
496+
with self.assertRaises(QiitaDBUnknownIDError):
497+
PreprocessedData.delete(ppd.id)
498+
499+
# testing that we can not remove cause the preprocessed data != sandbox
500+
with self.assertRaises(QiitaDBStatusError):
501+
PreprocessedData.delete(1)
502+
503+
def test_delete_advanced(self):
504+
# testing that we can not remove cause preprocessed data has been
505+
# submitted to EBI or VAMPS
506+
ppd = PreprocessedData.create(
507+
self.study, self.params_table,
508+
self.params_id, self.filepaths, prep_template=self.prep_template,
509+
ebi_submission_accession=self.ebi_submission_accession,
510+
ebi_study_accession=self.ebi_study_accession)
511+
512+
# fails due to VAMPS submission
513+
ppd.update_vamps_status('success')
514+
with self.assertRaises(QiitaDBStatusError):
515+
PreprocessedData.delete(ppd.id)
516+
ppd.update_vamps_status('failed')
517+
518+
# fails due to EBI submission
519+
ppd.update_insdc_status('success', 'AAAA', 'AAAA')
520+
with self.assertRaises(QiitaDBStatusError):
521+
PreprocessedData.delete(ppd.id)
522+
481523
def test_create_error_dynamic_table(self):
482524
"""Raises an error if the preprocessed_params_table does not exist"""
483525
with self.assertRaises(IncompetentQiitaDeveloperError):

qiita_pet/handlers/study_handlers/description_handlers.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,33 @@ def delete_prep_template(self, study, user, callback):
697697

698698
callback((msg, msg_level, 'raw_data_tab', prep_id, None))
699699

700+
def delete_preprocessed_data(self, study, user, callback):
701+
"""Delete the selected preprocessed data
702+
703+
Parameters
704+
----------
705+
study : Study
706+
The current study object
707+
user : User
708+
The current user object
709+
callback : function
710+
The callback function to call with the results once the processing
711+
is done
712+
"""
713+
ppd_id = int(self.get_argument('preprocessed_data_id'))
714+
715+
try:
716+
PreprocessedData.delete(ppd_id)
717+
msg = ("Preprocessed data %d has been deleted" % ppd_id)
718+
msg_level = "success"
719+
ppd_id = None
720+
except Exception as e:
721+
msg = ("Couldn't remove preprocessed data %d: %s" %
722+
(ppd_id, str(e)))
723+
msg_level = "danger"
724+
725+
callback((msg, msg_level, 'preprocessed_data_tab', ppd_id, None))
726+
700727
def delete_processed_data(self, study, user, callback):
701728
"""Delete the selected processed data
702729
@@ -756,6 +783,7 @@ def post(self, study_id):
756783
update_investigation_type=self.update_investigation_type,
757784
delete_raw_data=self.delete_raw_data,
758785
delete_prep_template=self.delete_prep_template,
786+
delete_preprocessed_data=self.delete_preprocessed_data,
759787
delete_processed_data=self.delete_processed_data)
760788

761789
# Get the action that we need to perform

0 commit comments

Comments
 (0)