From 6f98b690248697e0472be8b09bc417d7dc46f281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Poulain?= Date: Sat, 1 Aug 2020 22:17:15 +0200 Subject: [PATCH] =?UTF-8?q?feat(drupal):=20reconstruit=20la=20hi=C3=A9rarc?= =?UTF-8?q?hie=20de=20la=20DB=20pour=20que=20l=20ORM=20retrouve=20ses=20pe?= =?UTF-8?q?tits?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/management/commands/inspectdb.py | 99 ++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/drupal2spip_lal/base/management/commands/inspectdb.py b/drupal2spip_lal/base/management/commands/inspectdb.py index 1a95e2e..67b9927 100644 --- a/drupal2spip_lal/base/management/commands/inspectdb.py +++ b/drupal2spip_lal/base/management/commands/inspectdb.py @@ -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]