Diff of /qiita_db/reference.py [000000] .. [879b32]

Switch to unified view

a b/qiita_db/reference.py
1
# -----------------------------------------------------------------------------
2
# Copyright (c) 2014--, The Qiita Development Team.
3
#
4
# Distributed under the terms of the BSD 3-clause License.
5
#
6
# The full license is in the file LICENSE, distributed with this software.
7
# -----------------------------------------------------------------------------
8
from os.path import join
9
10
import qiita_db as qdb
11
12
13
class Reference(qdb.base.QiitaObject):
14
    r"""Object to interact with reference sequence databases
15
16
    Attributes
17
    ----------
18
    sequence_fp
19
    taxonomy_fp
20
    tree_fp
21
22
    Methods
23
    -------
24
    create
25
    exists
26
27
    See Also
28
    --------
29
    QiitaObject
30
    """
31
    _table = "reference"
32
33
    @classmethod
34
    def create(cls, name, version, seqs_fp, tax_fp=None, tree_fp=None):
35
        r"""Creates a new reference object with a new id on the storage system
36
37
        Parameters
38
        ----------
39
        name : str
40
            The name of the reference database
41
        version : str
42
            The version of the reference database
43
        seqs_fp : str
44
            The path to the reference sequence file
45
        tax_fp : str, optional
46
            The path to the reference taxonomy file
47
        tree_fp : str, optional
48
            The path to the reference tree file
49
50
        Returns
51
        -------
52
        A new instance of `cls` to access to the Reference stored in the DB
53
54
        Raises
55
        ------
56
        QiitaDBDuplicateError
57
            If the reference database with name `name` and version `version`
58
            already exists on the system
59
        """
60
        with qdb.sql_connection.TRN:
61
            if cls.exists(name, version):
62
                raise qdb.exceptions.QiitaDBDuplicateError(
63
                    "Reference", "Name: %s, Version: %s" % (name, version))
64
65
            fps = [(seqs_fp,
66
                    qdb.util.convert_to_id("reference_seqs", "filepath_type"))]
67
            seq_id = qdb.util.insert_filepaths(
68
                fps, "%s_%s" % (name, version), "reference")[0]
69
70
            # Check if the database has taxonomy file
71
            tax_id = None
72
            if tax_fp:
73
                fps = [
74
                    (tax_fp,
75
                     qdb.util.convert_to_id("reference_tax", "filepath_type"))]
76
                tax_id = qdb.util.insert_filepaths(
77
                    fps, "%s_%s" % (name, version), "reference")[0]
78
79
            # Check if the database has tree file
80
            tree_id = None
81
            if tree_fp:
82
                fps = [
83
                    (tree_fp,
84
                     qdb.util.convert_to_id("reference_tree", "filepath_type"))
85
                    ]
86
                tree_id = qdb.util.insert_filepaths(
87
                    fps, "%s_%s" % (name, version), "reference")[0]
88
89
            # Insert the actual object to the db
90
            sql = """INSERT INTO qiita.{0}
91
                        (reference_name, reference_version, sequence_filepath,
92
                         taxonomy_filepath, tree_filepath)
93
                     VALUES (%s, %s, %s, %s, %s)
94
                     RETURNING reference_id""".format(cls._table)
95
            qdb.sql_connection.TRN.add(
96
                sql, [name, version, seq_id, tax_id, tree_id])
97
            id_ = qdb.sql_connection.TRN.execute_fetchlast()
98
99
            return cls(id_)
100
101
    @classmethod
102
    def exists(cls, name, version):
103
        r"""Checks if a given object info is already present on the DB
104
105
        Parameters
106
        ----------
107
        name : str
108
            The name of the reference database
109
        version : str
110
            The version of the reference database
111
112
        Raises
113
        ------
114
        QiitaDBNotImplementedError
115
            If the method is not overwritten by a subclass
116
        """
117
        with qdb.sql_connection.TRN:
118
            sql = """SELECT EXISTS(
119
                        SELECT * FROM qiita.{0}
120
                        WHERE reference_name=%s
121
                            AND reference_version=%s)""".format(cls._table)
122
            qdb.sql_connection.TRN.add(sql, [name, version])
123
            return qdb.sql_connection.TRN.execute_fetchlast()
124
125
    @property
126
    def name(self):
127
        with qdb.sql_connection.TRN:
128
            sql = """SELECT reference_name FROM qiita.{0}
129
                     WHERE reference_id = %s""".format(self._table)
130
            qdb.sql_connection.TRN.add(sql, [self._id])
131
            return qdb.sql_connection.TRN.execute_fetchlast()
132
133
    @property
134
    def version(self):
135
        with qdb.sql_connection.TRN:
136
            sql = """SELECT reference_version FROM qiita.{0}
137
                     WHERE reference_id = %s""".format(self._table)
138
            qdb.sql_connection.TRN.add(sql, [self._id])
139
            return qdb.sql_connection.TRN.execute_fetchlast()
140
141
    def _retrieve_filepath(self, column):
142
        def path_builder(db_dir, filepath, mountpoint, subdirectory, obj_id):
143
            if subdirectory:
144
                return join(db_dir, mountpoint, str(obj_id), filepath)
145
            else:
146
                return join(db_dir, mountpoint, filepath)
147
148
        with qdb.sql_connection.TRN:
149
            sql = """SELECT filepath, mountpoint, subdirectory
150
                     FROM qiita.filepath f
151
                        JOIN qiita.filepath_type USING (filepath_type_id)
152
                        JOIN qiita.data_directory USING (data_directory_id)
153
                        JOIN qiita.{0} r ON r.{1} = f.filepath_id
154
                     WHERE r.reference_id = %s""".format(self._table, column)
155
            qdb.sql_connection.TRN.add(sql, [self._id])
156
            result = qdb.sql_connection.TRN.execute_fetchindex()
157
            if result:
158
                # If results is not empty, there will be only 1 result in the
159
                # list, hence using the 0 index
160
                fp, mountpoint, subdir = result[0]
161
                db_dir = qdb.util.get_db_files_base_dir()
162
                return path_builder(db_dir, fp, mountpoint, subdir, self._id)
163
            else:
164
                return ''
165
166
    @property
167
    def sequence_fp(self):
168
        return self._retrieve_filepath('sequence_filepath')
169
170
    @property
171
    def taxonomy_fp(self):
172
        return self._retrieve_filepath('taxonomy_filepath')
173
174
    @property
175
    def tree_fp(self):
176
        return self._retrieve_filepath('tree_filepath')