model.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. '''
  2. @author: olivier.massot, févr. 2018
  3. '''
  4. import csv
  5. from datetime import datetime
  6. import logging
  7. import dateutil.parser
  8. from core.sqlformatter import SqlFormatter
  9. logger = logging.getLogger("model")
  10. Sql = SqlFormatter()
  11. csv.register_dialect('tsv', delimiter='\t', quotechar='', quoting=csv.QUOTE_NONE)
  12. class Model():
  13. _mapping = {}
  14. def __setattr__(self, name, value):
  15. try:
  16. val, type_ = value
  17. if not type_ in (int, float, bool, str, datetime):
  18. raise TypeError("Type de donnée invalide pour une propriété de 'Model' ('{}')".format(type(val)))
  19. self.__class__._mapping[name] = type_
  20. except (TypeError, ValueError):
  21. val = value
  22. if val is None:
  23. super().__setattr__(name, val)
  24. return
  25. try:
  26. type_ = self.__class__._mapping[name]
  27. except KeyError:
  28. super().__setattr__(name, val)
  29. return
  30. val = Model._cast(val, type_)
  31. super().__setattr__(name, val)
  32. @staticmethod
  33. def _cast(value, type_):
  34. if value is None:
  35. return value
  36. if type_ == datetime:
  37. if type(value) is str:
  38. return dateutil.parser.parse(value)
  39. elif type(value) is datetime:
  40. return value
  41. else:
  42. raise ValueError("'{}' ne peut pas être converti en date".format(value))
  43. if type_ is bool and value in ("True", "False"):
  44. return (value == "True")
  45. else:
  46. return type_(value)
  47. @property
  48. def _fields(self):
  49. return list(self.__dict__.keys())
  50. @property
  51. def data(self):
  52. return self.__dict__
  53. def __repr__(self):
  54. return "<{} => {}>".format(self.__class__.__name__, ",".join(["{}={}".format(field, value) for field, value in self.__dict__.items()]))
  55. @classmethod
  56. def from_dict(cls, data):
  57. """ Retourne un objet à partir d'un dictionnaire de données """
  58. model = cls()
  59. for key, value in data.items():
  60. setattr(model, key, value)
  61. return model
  62. @classmethod
  63. def _parse(cls, field, value):
  64. if value == 'None':
  65. value = None
  66. try:
  67. return Model._cast(value, cls._mapping[field])
  68. except KeyError:
  69. return value