feat(drupal): reconstruit la hiérarchie de la DB pour que l ORM retrouve ses petits

This commit is contained in:
François Poulain 2020-08-01 22:17:15 +02:00
parent db85024859
commit 6f98b69024

View File

@ -6,6 +6,92 @@ from django.db import DEFAULT_DB_ALIAS, connections
from django.db.models.constants import LOOKUP_SEP
# On reconstruit ici la hiérarchie de la DB que les dev php n'ont pas été
# capables de spécifier en sql. On en profite pour donner des noms explicites.
DB_RELATIONS = {
'drupal': {
'content_type_event': {
'nid': ('nid', 'node', 'node'),
'vid': ('vid', 'node_revisions', 'revision'),
},
'content_type_revue_de_presse': {
'nid': ('nid', 'node', 'node'),
'vid': ('vid', 'node_revisions', 'revision'),
},
'enclosure': {
'nid': ('nid', 'node', 'node'),
},
'event': {
'nid': ('nid', 'node', 'node'),
},
'i18n_node': {
'language': ('language', 'languages'),
'nid': ('nid', 'node', 'node'),
},
'files': {
'uid': ('uid', 'users', 'user'),
},
'history': {
'uid': ('uid', 'users', 'user'),
'nid': ('nid', 'node', 'node'),
},
'node': {
'uid': ('uid', 'users', 'user'),
# nb: vid est en redondance avec node_revisions.nid
# ceci étant la db est cohérente de ce point de vue
'vid': ('vid', 'node_revisions', 'published_revision', '+'),
'language': ('language', 'languages'),
'tnid': ('nid', 'node', 'translation source', '+'),
},
'node_revisions': {
'nid': ('nid', 'node', 'node'),
'uid': ('uid', 'users', 'user'),
'format': ('format', 'FilterFormats'),
},
'node_access': {
'nid': ('nid', 'node', 'node'),
'gid': ('tid', 'term_data', 'permission'),
},
'term_data': {
'vid': ('vid', 'vocabulary', 'theme'),
# nb: trid est un identifiant pour grouper les différentes
# variantes des termes pour dans différents langages (clé commune)
},
'term_node': {
'nid': ('nid', 'node', 'node'),
'tid': ('tid', 'term_data', 'data'),
'vid': ('vid', 'node_revisions', 'revision'),
},
'term_synonym': {
'tid': ('tid', 'term_data', 'data'),
},
'upload': {
'fid': ('fid', 'files', 'file'),
'uid': ('uid', 'users', 'user'),
'nid': ('nid', 'node', 'node'),
'vid': ('vid', 'node_revisions', 'revision'),
},
'url_alias': {
'language': ('language', 'languages'),
},
'users_roles': {
'rid': ('rid', 'role', 'role'),
'uid': ('uid', 'users', 'user'),
},
'vocabulary': {
'language': ('language', 'languages'),
},
'vocabulary_node_types': {
'vid': ('vid', 'node_revisions', 'revision'),
'type': ('type', 'node_type', 'node_type'),
},
},
'spip': {
}
}
class Command(BaseCommand):
help = "Introspects the database tables in the given database and outputs a Django model module."
requires_system_checks = False
@ -80,6 +166,7 @@ class Command(BaseCommand):
try:
try:
relations = connection.introspection.get_relations(cursor, table_name)
relations.update(DB_RELATIONS[options['database']].get(table_name, {}))
except NotImplementedError:
relations = {}
try:
@ -112,7 +199,8 @@ class Command(BaseCommand):
is_pk = column_name == primary_key_column
has_pk = primary_key_column
att_name, params, notes = self.normalize_col_name(
column_name, used_column_names, is_relation, is_pk, has_pk)
column_name, used_column_names, is_relation, is_pk, has_pk, relations
)
extra_params.update(params)
comment_notes.extend(notes)
@ -130,6 +218,8 @@ class Command(BaseCommand):
rel_type = 'OneToOneField'
else:
rel_type = 'ForeignKey'
if len(relations[column_name]) > 3:
extra_params['related_name'] = relations[column_name][3]
rel_to = (
"self" if relations[column_name][1] == table_name
else table2model(relations[column_name][1])
@ -183,7 +273,7 @@ class Command(BaseCommand):
for meta_line in self.get_meta(table_name, constraints, column_to_field_name, is_view, is_partition):
yield meta_line
def normalize_col_name(self, col_name, used_column_names, is_relation, is_pk, has_pk):
def normalize_col_name(self, col_name, used_column_names, is_relation, is_pk, has_pk, relations):
"""
Modify the column name to make it Python-compatible as a field name
"""
@ -191,9 +281,14 @@ class Command(BaseCommand):
field_notes = []
new_name = col_name.lower()
if new_name != col_name:
field_notes.append('Field name made lowercase.')
if len(relations.get(col_name, [])) >= 3:
new_name = relations[col_name][2]
field_notes = ['Field named from forced relations.']
if is_relation:
if new_name.endswith('_id'):
new_name = new_name[:-3]