|
44 | 44 |
|
45 | 45 | from qiita_core.exceptions import IncompetentQiitaDeveloperError
|
46 | 46 | from qiita_db.exceptions import (QiitaDBUnknownIDError,
|
47 |
| - QiitaDBNotImplementedError) |
| 47 | + QiitaDBNotImplementedError, |
| 48 | + QiitaDBColumnError) |
48 | 49 | from qiita_db.base import QiitaObject
|
49 | 50 | from qiita_db.sql_connection import SQLConnectionHandler
|
50 | 51 | from qiita_db.util import (exists_table, get_table_cols,
|
@@ -308,17 +309,79 @@ def handler(x):
|
308 | 309 | " in template %d" %
|
309 | 310 | (key, self._id, self._md_template.id))
|
310 | 311 |
|
311 |
| - def __setitem__(self, key, value): |
312 |
| - r"""Sets the metadata value for the category `key` |
| 312 | + def __setitem__(self, column, value): |
| 313 | + r"""Sets the metadata value for the category `column` |
313 | 314 |
|
314 | 315 | Parameters
|
315 | 316 | ----------
|
316 |
| - key : str |
317 |
| - The metadata category |
318 |
| - value : obj |
319 |
| - The new value for the category |
| 317 | + column : str |
| 318 | + The column to update |
| 319 | + value : str |
| 320 | + The value to set. This is expected to be a str on the assumption |
| 321 | + that psycopg2 will cast as necessary when updating. |
| 322 | +
|
| 323 | + Raises |
| 324 | + ------ |
| 325 | + QiitaDBColumnError |
| 326 | + If the column does not exist in the table |
320 | 327 | """
|
321 |
| - raise QiitaDBNotImplementedError() |
| 328 | + conn_handler = SQLConnectionHandler() |
| 329 | + |
| 330 | + # try dynamic tables |
| 331 | + sql = """SELECT EXISTS ( |
| 332 | + SELECT column_name |
| 333 | + FROM information_schema.columns |
| 334 | + WHERE table_name=%s |
| 335 | + AND table_schema='qiita' |
| 336 | + AND column_name=%s)""" |
| 337 | + exists_dynamic = conn_handler.execute_fetchone( |
| 338 | + sql, (self._dynamic_table, column))[0] |
| 339 | + # try required_sample_info |
| 340 | + sql = """SELECT EXISTS ( |
| 341 | + SELECT column_name |
| 342 | + FROM information_schema.columns |
| 343 | + WHERE table_name=%s |
| 344 | + AND table_schema='qiita' |
| 345 | + AND column_name=%s)""" |
| 346 | + exists_required = conn_handler.execute_fetchone( |
| 347 | + sql, (self._table, column))[0] |
| 348 | + |
| 349 | + if exists_dynamic: |
| 350 | + # catching error so we can check if the error is due to different |
| 351 | + # column type or something else |
| 352 | + try: |
| 353 | + sql = """UPDATE qiita.{0} |
| 354 | + SET {1}=%s |
| 355 | + WHERE sample_id=%s""".format(self._dynamic_table, |
| 356 | + column) |
| 357 | + conn_handler.execute(sql, (value, self._id)) |
| 358 | + except Exception as e: |
| 359 | + column_type = conn_handler.execute_fetchone( |
| 360 | + """SELECT data_type |
| 361 | + FROM information_schema.columns |
| 362 | + WHERE column_name=%s AND table_schema='qiita' |
| 363 | + """, (column,))[0] |
| 364 | + value_type = type(value).__name__ |
| 365 | + |
| 366 | + if column_type != value_type: |
| 367 | + raise ValueError( |
| 368 | + 'The new value being added to column: "{0}" is "{1}" ' |
| 369 | + '(type: "{2}"). However, this column in the DB is of ' |
| 370 | + 'type "{3}". Please change the value in your updated ' |
| 371 | + 'template or reprocess your sample template.'.format( |
| 372 | + column, value, value_type, column_type)) |
| 373 | + else: |
| 374 | + raise e |
| 375 | + elif exists_required: |
| 376 | + # here is not required the type check as the required fields have |
| 377 | + # an explicit type check |
| 378 | + sql = """UPDATE qiita.{0} |
| 379 | + SET {1}=%s |
| 380 | + WHERE sample_id=%s""".format(self._table, column) |
| 381 | + conn_handler.execute(sql, (value, self._id)) |
| 382 | + else: |
| 383 | + raise QiitaDBColumnError("Column %s does not exist in %s" % |
| 384 | + (column, self._dynamic_table)) |
322 | 385 |
|
323 | 386 | def __delitem__(self, key):
|
324 | 387 | r"""Removes the sample with sample id `key` from the database
|
|
0 commit comments