|
45 | 45 | from skbio.util import find_duplicates |
46 | 46 |
|
47 | 47 | from qiita_core.exceptions import IncompetentQiitaDeveloperError |
| 48 | + |
48 | 49 | from qiita_db.exceptions import (QiitaDBUnknownIDError, QiitaDBColumnError, |
49 | 50 | QiitaDBNotImplementedError, |
50 | 51 | QiitaDBDuplicateHeaderError) |
@@ -312,17 +313,81 @@ def handler(x): |
312 | 313 | " in template %d" % |
313 | 314 | (key, self._id, self._md_template.id)) |
314 | 315 |
|
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` |
317 | 318 |
|
318 | 319 | Parameters |
319 | 320 | ---------- |
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 |
324 | 333 | """ |
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 |
326 | 391 |
|
327 | 392 | def __delitem__(self, key): |
328 | 393 | r"""Removes the sample with sample id `key` from the database |
|
0 commit comments