Skip to content

Commit 5a38e03

Browse files
committed
merge upstream/master
2 parents 77b311c + 559556e commit 5a38e03

File tree

11 files changed

+316
-54
lines changed

11 files changed

+316
-54
lines changed

qiita_db/data.py

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
from .base import QiitaObject
8686
from .logger import LogEntry
8787
from .sql_connection import SQLConnectionHandler
88-
from .exceptions import QiitaDBError
88+
from .exceptions import QiitaDBError, QiitaDBUnknownIDError
8989
from .util import (exists_dynamic_table, insert_filepaths, convert_to_id,
9090
convert_from_id, purge_filepaths, get_filepath_id,
9191
get_mountpoint, move_filepaths_to_upload_folder)
@@ -243,6 +243,27 @@ def _set_link_filepaths_status(self, status):
243243
"WHERE {1} = %s".format(self._table, self._data_filepath_column),
244244
(status, self._id))
245245

246+
@classmethod
247+
def exists(cls, object_id):
248+
r"""Checks if the given object_id exists
249+
250+
Parameters
251+
----------
252+
id : str
253+
The id of the object we are searching for
254+
255+
Returns
256+
-------
257+
bool
258+
True if exists, false otherwise.
259+
"""
260+
conn_handler = SQLConnectionHandler()
261+
262+
return conn_handler.execute_fetchone(
263+
"SELECT EXISTS(SELECT * FROM qiita.{0} WHERE "
264+
"{1}=%s)".format(cls._table, cls._data_filepath_column),
265+
(object_id, ))[0]
266+
246267

247268
class RawData(BaseData):
248269
r"""Object for dealing with raw data
@@ -308,6 +329,81 @@ def create(cls, filetype, studies, filepaths=None):
308329

309330
return rd
310331

332+
@classmethod
333+
def delete(cls, raw_data_id, study_id):
334+
"""Removes the raw data with id raw_data_id
335+
336+
Parameters
337+
----------
338+
raw_data_id : int
339+
The raw data id
340+
study_id : int
341+
The study id
342+
343+
Raises
344+
------
345+
QiitaDBUnknownIDError
346+
If the raw data id doesn't exist
347+
QiitaDBError
348+
If the raw data is not linked to that study_id
349+
If the raw data has prep templates associated
350+
"""
351+
conn_handler = SQLConnectionHandler()
352+
353+
# check if the raw data exist
354+
if not cls.exists(raw_data_id):
355+
raise QiitaDBUnknownIDError(raw_data_id, "raw data")
356+
357+
study_raw_data_exists = conn_handler.execute_fetchone(
358+
"SELECT EXISTS(SELECT * FROM qiita.study_raw_data WHERE "
359+
"study_id = {0} AND raw_data_id = {1})".format(study_id,
360+
raw_data_id))[0]
361+
if not study_raw_data_exists:
362+
raise QiitaDBError(
363+
"Raw data %d is not linked to study %d or the study "
364+
"doesn't exist" % (raw_data_id, study_id))
365+
366+
# check if there are any prep templates for this study
367+
prep_template_exists = conn_handler.execute_fetchone(
368+
"""
369+
SELECT EXISTS(
370+
SELECT * FROM qiita.prep_template AS pt
371+
LEFT JOIN qiita.common_prep_info AS cpi ON
372+
(pt.prep_template_id=cpi.prep_template_id)
373+
LEFT JOIN qiita.required_sample_info AS rsi ON
374+
(cpi.sample_id=rsi.sample_id)
375+
WHERE raw_data_id = {0} and study_id = {1}
376+
)
377+
""".format(raw_data_id, study_id))[0]
378+
if prep_template_exists:
379+
raise QiitaDBError(
380+
"Raw data %d has prep template(s) associated so it can't be "
381+
"erased." % raw_data_id)
382+
383+
# check how many raw data are left, if last one, check that there
384+
# are no linked files
385+
raw_data_count = conn_handler.execute_fetchone(
386+
"SELECT COUNT(*) FROM qiita.study_raw_data WHERE "
387+
"raw_data_id = {0}".format(raw_data_id))[0]
388+
if raw_data_count == 1 and RawData(raw_data_id).get_filepath_ids():
389+
raise QiitaDBError(
390+
"Raw data (%d) can't be remove because it has linked files. "
391+
"To remove it, first unlink files." % raw_data_id)
392+
393+
# delete
394+
conn_handler.execute("DELETE FROM qiita.study_raw_data WHERE "
395+
"raw_data_id = {0} AND "
396+
"study_id = {1}".format(raw_data_id, study_id))
397+
398+
# delete the connecting tables if there is no other study linked to
399+
# the raw data
400+
study_raw_data_count = conn_handler.execute_fetchone(
401+
"SELECT COUNT(*) FROM qiita.study_raw_data WHERE "
402+
"raw_data_id = {0}".format(raw_data_id))[0]
403+
if study_raw_data_count == 0:
404+
conn_handler.execute("DELETE FROM qiita.raw_data WHERE "
405+
"raw_data_id = {0}".format(raw_data_id))
406+
311407
@property
312408
def studies(self):
313409
r"""The IDs of the studies to which this raw data belongs

qiita_db/metadata_template.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1858,7 +1858,7 @@ def create_qiime_mapping_file(self, prep_template_fp):
18581858
str(pt_sample_names-st_sample_names)))
18591859

18601860
mapping = pt.join(st, lsuffix="_prep")
1861-
mapping.rename(columns=rename_cols, inplace=True, index=str.lower)
1861+
mapping.rename(columns=rename_cols, inplace=True)
18621862

18631863
# Gets the orginal mapping columns and readjust the order to comply
18641864
# with QIIME requirements

qiita_db/support_files/patches/14.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
21
--Feb 11, 2015
32
--Placeholder for python to run
4-
select * from settings;
3+
-- we don't really need an SQL patch, but having nothing here breaks the build
4+
select 42;

qiita_db/support_files/patches/15.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
--Feb 11, 2015
2+
--Placeholder for python to run
3+
-- we don't really need an SQL patch, but having nothing here breaks the build
4+
select 42;
Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,74 @@
1-
# Feb 11, 2015
2-
# This changes all analysis files to be relative path instead of absolute
1+
# Feberuary 7, 2015
2+
# This patch recreates all the QIIME mapping files to avoid lower/upper case
3+
# problems. See https://github.com/biocore/qiita/issues/799
4+
#
5+
# heavily based on 7.py
36

4-
from os.path import basename, dirname
7+
from os.path import basename
8+
9+
from skbio.util import flatten
510

6-
from qiita_db.util import get_mountpoint
711
from qiita_db.sql_connection import SQLConnectionHandler
12+
from qiita_db.metadata_template import PrepTemplate
813

914
conn_handler = SQLConnectionHandler()
1015

11-
filepaths = conn_handler.execute_fetchall(
12-
'SELECT f.* from qiita.filepath f JOIN qiita.analysis_filepath afp ON '
13-
'f.filepath_id = afp.filepath_id')
14-
15-
# retrieve relative filepaths as dictionary for matching
16-
mountpoints = {m[1].rstrip('/\\'): m[0] for m in get_mountpoint(
17-
'analysis', conn_handler=conn_handler, retrieve_all=True)}
18-
19-
for filepath in filepaths:
20-
filename = basename(filepath['filepath'])
21-
# find the ID of the analysis filepath used
22-
mp_id = mountpoints[dirname(filepath['filepath']).rstrip('/\\')]
23-
conn_handler.execute(
24-
'UPDATE qiita.filepath SET filepath = %s, data_directory_id = %s WHERE'
25-
' filepath_id = %s',
26-
[filename, mp_id, filepath['filepath_id']])
16+
sql = "SELECT prep_template_id FROM qiita.prep_template"
17+
all_ids = conn_handler.execute_fetchall(sql)
18+
19+
q_name = 'unlink-bad-mapping-files'
20+
conn_handler.create_queue(q_name)
21+
22+
# remove all the bad mapping files
23+
for prep_template_id in all_ids:
24+
25+
prep_template_id = prep_template_id[0]
26+
pt = PrepTemplate(prep_template_id)
27+
fps = pt.get_filepaths()
28+
29+
# get the QIIME mapping file, note that the way to figure out what is and
30+
# what's not a qiime mapping file is to check for the existance of the
31+
# word qiime in the basename of the file path, hacky but that's the way
32+
# it is being done in qiita_pet/uimodules/raw_data_tab.py
33+
mapping_files = [f for f in fps if '_qiime_' in basename(f[1])]
34+
35+
table = 'prep_template_filepath'
36+
column = 'prep_template_id'
37+
38+
# unlink all the qiime mapping files for this prep template object
39+
for mf in mapping_files:
40+
41+
# (1) get the ids that we are going to delete.
42+
# because of the FK restriction, we cannot just delete the ids
43+
ids = conn_handler.execute_fetchall(
44+
'SELECT filepath_id FROM qiita.{0} WHERE '
45+
'{1}=%s and filepath_id=%s'.format(table, column), (pt.id, mf[0]))
46+
ids = flatten(ids)
47+
48+
# (2) delete the entries from the prep_template_filepath table
49+
conn_handler.add_to_queue(
50+
q_name, "DELETE FROM qiita.{0} "
51+
"WHERE {1}=%s and filepath_id=%s;".format(table, column),
52+
(pt.id, mf[0]))
53+
54+
# (3) delete the entries from the filepath table
55+
conn_handler.add_to_queue(
56+
q_name,
57+
"DELETE FROM qiita.filepath WHERE "
58+
"filepath_id IN ({0});".format(', '.join(map(str, ids))))
59+
60+
try:
61+
conn_handler.execute_queue(q_name)
62+
except Exception as e:
63+
raise
64+
65+
# create correct versions of the mapping files
66+
for prep_template_id in all_ids:
67+
68+
prep_template_id = prep_template_id[0]
69+
pt = PrepTemplate(prep_template_id)
70+
71+
# we can guarantee that all the filepaths will be prep templates so
72+
# we can just generate the qiime mapping files
73+
for _, fpt in pt.get_filepaths():
74+
pt.create_qiime_mapping_file(fpt)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Feb 11, 2015
2+
# This changes all analysis files to be relative path instead of absolute
3+
4+
from os.path import basename, dirname
5+
6+
from qiita_db.util import get_mountpoint
7+
from qiita_db.sql_connection import SQLConnectionHandler
8+
9+
conn_handler = SQLConnectionHandler()
10+
11+
filepaths = conn_handler.execute_fetchall(
12+
'SELECT f.* from qiita.filepath f JOIN qiita.analysis_filepath afp ON '
13+
'f.filepath_id = afp.filepath_id')
14+
15+
# retrieve relative filepaths as dictionary for matching
16+
mountpoints = {m[1].rstrip('/\\'): m[0] for m in get_mountpoint(
17+
'analysis', conn_handler=conn_handler, retrieve_all=True)}
18+
19+
for filepath in filepaths:
20+
filename = basename(filepath['filepath'])
21+
# find the ID of the analysis filepath used
22+
mp_id = mountpoints[dirname(filepath['filepath']).rstrip('/\\')]
23+
conn_handler.execute(
24+
'UPDATE qiita.filepath SET filepath = %s, data_directory_id = %s WHERE'
25+
' filepath_id = %s',
26+
[filename, mp_id, filepath['filepath_id']])

0 commit comments

Comments
 (0)