Queer European MD passionate about IT

database.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. """Provide any inheriting object with a dataset-powered database management."""
  2. # Standard library modules
  3. import logging
  4. # Third party modules
  5. import dataset
  6. class ObjectWithDatabase(object):
  7. """Objects inheriting from this class will have a `.db` method.
  8. Using `subclass_instance.db` will open a SQL transaction.
  9. To perform multiple SQL queries in a single transaction use a with
  10. statement as in this simple example:
  11. ```
  12. with my_object.db as db:
  13. if db['my_table'].find_one(id=14):
  14. db['fourteen_exists'].insert(
  15. {'exists': True}
  16. )
  17. ```
  18. """
  19. def __init__(self, database_url=None):
  20. """Instantiate object and open connection with database."""
  21. if database_url is None:
  22. database_url = 'database.db'
  23. if ':///' not in database_url:
  24. # Default database engine is sqlite, which operates on a
  25. # single-file database having `.db` extension
  26. if not database_url.endswith('.db'):
  27. database_url += '.db'
  28. database_url = f'sqlite:///{database_url}'
  29. self._database_url = database_url
  30. try:
  31. self._database = dataset.connect(self.db_url)
  32. except Exception as e:
  33. self._database_url = None
  34. self._database = None
  35. logging.error(f"{e}")
  36. @property
  37. def db_url(self):
  38. """Return complete path to database."""
  39. return self._database_url
  40. @property
  41. def db(self):
  42. """Return the dataset.Database instance related to `self`."""
  43. return self._database
  44. def create_views(self, views, overwrite=False):
  45. """Take a list of `views` and add them to bot database.
  46. Overwrite existing views if `overwrite` is set to True.
  47. Each element of this list should have
  48. - a `name` field
  49. - a `query field`
  50. """
  51. with self.db as db:
  52. for view in views:
  53. try:
  54. if overwrite:
  55. db.query(
  56. f"DROP VIEW IF EXISTS {view['name']}"
  57. )
  58. db.query(
  59. f"CREATE VIEW IF NOT EXISTS {view['name']} "
  60. f"AS {view['query']}"
  61. )
  62. except Exception as e:
  63. logging.error(f"{e}")