db.py 3.8 KB

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