No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sqlsetup.py 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. # -*- coding: utf-8 -*-
  2. import sqlalchemy as sql
  3. import re # Converting string to sqlalchemy types
  4. from Database import sqlutils
  5. def init_db(dbconfname='default', alchemy_logs=None, schema=None):
  6. dbe = sqlutils.get_engine(dbconfname, alchemy_logs)
  7. meta = sqlutils.meta(dbe)
  8. meta.reflect()
  9. meta.drop_all(dbe)
  10. # refresh meta (maybe useless)
  11. meta = sqlutils.meta(dbe)
  12. meta.reflect()
  13. if schema is None:
  14. schema = get_schema()
  15. for table in schema:
  16. topt = table.copy()
  17. del topt['columns']
  18. name = topt['name']
  19. del topt['name']
  20. cur_table = sql.Table(name, meta, **topt)
  21. for col in table['columns']:
  22. cur_col = create_column(**col)
  23. cur_table.append_column(cur_col)
  24. meta.create_all(bind=dbe)
  25. def get_schema():
  26. tables = []
  27. default_columns = [
  28. {"name": "uid", "type": "INTEGER", "extra": {"foreignkey": "uids.uid", "nullable": False, "primarykey": True}},
  29. {"name": "name", "type": "VARCHAR(50)", "extra": {"nullable": False, "unique": True}},
  30. {"name": "string", "type": "TEXT"},
  31. {"name": "help", "type": "TEXT"},
  32. {"name": "rank", "type": "INTEGER"},
  33. {"name": "date_create", "type": "DATETIME"},
  34. {"name": "date_update", "type": "DATETIME"},
  35. ]
  36. # Table listing all objects created by lodel, giving them an unique id
  37. uids = {
  38. "name": "uids",
  39. "columns": [
  40. {"name": "uid", "type": "INTEGER", "extra": {"nullable": False, "primarykey": True, 'autoincrement': True}},
  41. {"name": "table", "type": "VARCHAR(50)"}
  42. ]
  43. }
  44. tables.append(uids)
  45. # Table listing the classes
  46. em_class = {"name": "em_class"}
  47. em_class['columns'] = default_columns + [
  48. {"name": "classtype", "type": "VARCHAR(50)"},
  49. {"name": "sortcolumn", "type": "VARCHAR(50)", "extra": {"default": "rank"}},
  50. {"name": "icon", "type": "INTEGER"},
  51. ]
  52. tables.append(em_class)
  53. # Table listing the types
  54. em_type = {"name": "em_type"}
  55. em_type['columns'] = default_columns + [
  56. {"name": "class_id", "type": "INTEGER", "extra": {"foreignkey": "em_class.uid", "nullable": False}},
  57. {"name": "sortcolumn", "type": "VARCHAR(50)", "extra": {"default": "rank"}},
  58. {"name": "icon", "type": "INTEGER"},
  59. ]
  60. tables.append(em_type)
  61. # relation between types: which type can be a child of another
  62. em_type_hierarchy = {"name": "em_type_hierarchy"}
  63. em_type_hierarchy['columns'] = [
  64. {"name": "superior_id", "type": "INTEGER", "extra": {"foreignkey": "em_type.uid", "nullable": False, "primarykey": True}},
  65. {"name": "subordinate_id", "type": "INTEGER", "extra": {"foreignkey": "em_type.uid", "nullable": False, "primarykey": True}},
  66. {"name": "nature", "type": "VARCHAR(50)", "extra": {"primarykey": True}},
  67. ]
  68. tables.append(em_type_hierarchy)
  69. # Table listing the fieldgroups of a class
  70. em_fieldgroup = {"name": "em_fieldgroup"}
  71. em_fieldgroup['columns'] = default_columns + [
  72. {"name": "class_id", "type": "INTEGER", "extra": {"foreignkey": "em_class.uid", "nullable": False}},
  73. ]
  74. tables.append(em_fieldgroup)
  75. # Table listing the fields of a fieldgroup
  76. em_field = {"name": "em_field"}
  77. em_field['columns'] = default_columns + [
  78. {"name": "fieldtype", "type": "VARCHAR(50)", "extra": {"nullable": False}},
  79. {"name": "fieldgroup_id", "type": "INTEGER", "extra": {"foreignkey": "em_fieldgroup.uid", "nullable": False}},
  80. {"name": "rel_to_type_id", "type": "INTEGER", "extra": {"foreignkey": "em_type.uid", "nullable": True, "server_default": sql.text('NULL')}}, # if relational: type this field refer to
  81. {"name": "rel_field_id", "type": "INTEGER", "extra": {"foreignkey": "em_type.uid", "nullable": True, "server_default": sql.text('NULL')}}, # if relational: field that specify the rel_to_type_id
  82. {"name": "optional", "type": "BOOLEAN"},
  83. {"name": "internal", "type": "BOOLEAN"},
  84. {"name": "icon", "type": "INTEGER"},
  85. ]
  86. tables.append(em_field)
  87. # selected field for each type
  88. em_field_type = {"name": "em_field_type"}
  89. em_field_type['columns'] = [
  90. {"name": "type_id", "type": "INTEGER", "extra": {"foreignkey": "em_type.uid", "nullable": False, "primarykey": True}},
  91. {"name": "field_id", "type": "INTEGER", "extra": {"foreignkey": "em_field.uid", "nullable": False, "primarykey": True}},
  92. ]
  93. tables.append(em_field_type)
  94. # Table of the objects created by the user (instance of the types)
  95. objects = {
  96. "name": "objects",
  97. "columns": [
  98. {"name": "uid", "type": "INTEGER", "extra": {"foreignkey": "uids.uid", "nullable": False, "primarykey": True}},
  99. {"name": "string", "type": "VARCHAR(50)"},
  100. {"name": "class_id", "type": "INTEGER", "extra": {"foreignkey": "em_class.uid"}},
  101. {"name": "type_id", "type": "INTEGER", "extra": {"foreignkey": "em_type.uid"}},
  102. {"name": "date_create", "type": "DATETIME"},
  103. {"name": "date_update", "type": "DATETIME"},
  104. {"name": "history", "type": "TEXT"}
  105. ]
  106. }
  107. tables.append(objects)
  108. # Table listing all files
  109. files = {
  110. "name": "files",
  111. "columns": [
  112. {"name": "uid", "type": "INTEGER", "extra": {"foreignkey": "uids.uid", "nullable": False, "primarykey": True}},
  113. {"name": "field1", "type": "VARCHAR(50)"}
  114. ]
  115. }
  116. tables.append(files)
  117. return tables
  118. def create_column(**kwargs):
  119. #Converting parameters
  120. if 'type_' not in kwargs and 'type' in kwargs:
  121. kwargs['type_'] = string_to_sqla_type(kwargs['type'])
  122. del kwargs['type']
  123. if 'extra' in kwargs:
  124. # put the extra keys in kwargs
  125. for exname in kwargs['extra']:
  126. kwargs[exname] = kwargs['extra'][exname]
  127. del kwargs['extra']
  128. if 'foreignkey' in kwargs:
  129. # Instanciate a fk
  130. foreignkey = sql.ForeignKey(kwargs['foreignkey'])
  131. del kwargs['foreignkey']
  132. else:
  133. foreignkey = None
  134. if 'primarykey' in kwargs:
  135. # renaming primary_key in primarykey in kwargs
  136. kwargs['primary_key'] = kwargs['primarykey']
  137. del kwargs['primarykey']
  138. col = sql.Column(**kwargs)
  139. if foreignkey is not None:
  140. col.append_foreign_key(foreignkey)
  141. return col
  142. def string_to_sqla_type(strtype):
  143. """ Convert a string to an sqlAlchemy column type """
  144. if 'VARCHAR' in strtype:
  145. return string_to_varchar(strtype)
  146. else:
  147. try:
  148. return getattr(sql, strtype)
  149. except AttributeError:
  150. raise NameError("Unknown type '" + strtype + "'")
  151. def string_to_varchar(vstr):
  152. """ Convert a string like 'VARCHAR(XX)' (with XX an integer) to a SqlAlchemy varchar type"""
  153. check_length = re.search(re.compile('VARCHAR\(([\d]+)\)', re.IGNORECASE), vstr)
  154. column_length = int(check_length.groups()[0]) if check_length else None
  155. return sql.VARCHAR(length=column_length)