db.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. '''
  2. Convenient access to various databases
  3. '''
  4. import logging
  5. from pypyodbc import Connection
  6. logger = logging.getLogger("database")
  7. class CustomDb(Connection):
  8. """ Connexion to a database """
  9. _cache = {}
  10. default_name = ""
  11. drivername = ""
  12. dsn = ""
  13. default_user = ""
  14. default_pwd = ""
  15. def __init__(self, **kwargs):
  16. cls = self.__class__
  17. if not "uid" in kwargs and cls.default_user:
  18. kwargs["uid"] = cls.default_user
  19. if not "pwd" in kwargs and cls.default_pwd:
  20. kwargs["pwd"] = cls.default_pwd
  21. super(CustomDb, self).__init__(cls.dsn, **kwargs)
  22. def connect(self, *args, **kwargs):
  23. """ Establish the connexion to the database"""
  24. logger.info("Connection to %s: %s", self.__class__.__name__, self.connectString)
  25. super(CustomDb, self).connect(*args, **kwargs)
  26. def read(self, sql, *args):
  27. """ yield rows as NamedTupleRow """
  28. cursor = self.execute(sql)
  29. row = cursor.fetchone()
  30. while row:
  31. yield dict(zip([column[0] for column in cursor.description], row))
  32. row = cursor.fetchone()
  33. cursor.close()
  34. def read_all(self, sql, *args):
  35. """ return the selection as a list of dictionnaries """
  36. cursor = self.execute(sql)
  37. data = [dict(zip([column[0] for column in cursor.description], row)) for row in cursor.fetchall()]
  38. cursor.close()
  39. return data
  40. def first(self, sql, *args):
  41. try:
  42. return next(self.read(sql, *args))
  43. except StopIteration:
  44. return None
  45. def execute(self, sql, *args):
  46. cursor = self.cursor()
  47. args = [sql, tuple(args)] if args else [sql]
  48. cursor.execute(*args)
  49. return cursor
  50. class AccessDb(CustomDb):
  51. dsn = "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};FIL={MS Access};"
  52. default_user = "admin"
  53. default_pwd = ""
  54. def __init__(self, dbpath, **kwargs):
  55. super(AccessDb, self).__init__(dbq=dbpath, **kwargs)
  56. def assert_connected(self):
  57. for row in self.read("SELECT TOP 1 * FROM MSysObjects;"):
  58. if not row:
  59. raise AssertionError("Unable to connect to: {}".format(self.connectString))
  60. return
  61. class AccessSDb(AccessDb):
  62. dsn = "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};FIL={MS Access};"
  63. default_user = ""
  64. default_pwd = ""
  65. def __init__(self, dbpath, mdwpath, uid, pwd, **kwargs):
  66. super(AccessSDb, self).__init__(dbpath, uid=uid, pwd=pwd, systemdb=mdwpath, **kwargs)
  67. class OracleDb(CustomDb):
  68. dsn = "DRIVER={Oracle dans ORA102};"
  69. def __init__(self, dbname, user, pwd, **kwargs):
  70. super(OracleDb, self).__init__(dbq=dbname, uid=user, pwd=pwd, **kwargs)
  71. class SqlServerDb(CustomDb):
  72. dsn = "DRIVER={SQL Server};"
  73. def __init__(self, server, dbname, user, pwd, **kwargs):
  74. super(SqlServerDb, self).__init__(server=server, database=dbname, uid=user, pwd=pwd, **kwargs)
  75. # class SqliteDb(CustomDb):
  76. # drivername = "QODBC"
  77. # dsn = "DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};FIL={{MS Access}}"
  78. # default_user = "admin"
  79. # pwd = ""
  80. # def __init__(self, dbpath, **kwargs):
  81. # CustomDb.__init__(self, dbq=dbpath, **kwargs)
  82. #
  83. # class PostgresDb(CustomDb):
  84. # drivername = "QODBC"
  85. # dsn = "DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};FIL={{MS Access}}"
  86. # default_user = "admin"
  87. # pwd = ""
  88. # def __init__(self, dbpath, **kwargs):
  89. # CustomDb.__init__(self, dbq=dbpath, **kwargs)