| 1 | # encoding: utf-8 |
| 2 | |
| 3 | from django import db |
| 4 | from django.db.models.signals import post_syncdb |
| 5 | from django.dispatch import receiver |
| 6 | |
| 7 | import auf.django.references.models |
| 8 | |
| 9 | |
| 10 | @receiver(post_syncdb, sender=auf.django.references.models) |
| 11 | def creer_vues(sender, **kwargs): |
| 12 | """Création des vues vers datamaster.""" |
| 13 | |
| 14 | verbosity = kwargs.get('verbosity', 1) |
| 15 | |
| 16 | # On ne crée des vues que si on est sur une BD MySQL. |
| 17 | # L'attribut db.connection.vendor n'est présent qu'à partir de Django |
| 18 | # 1.3 |
| 19 | if (hasattr(db.connection, 'vendor') |
| 20 | and db.connection.vendor != 'mysql') or \ |
| 21 | 'mysql' not in db.backend.__name__: |
| 22 | return |
| 23 | |
| 24 | cursor = db.connection.cursor() |
| 25 | |
| 26 | # Vérifions qu'on a une BD qui s'appelle 'datamaster' |
| 27 | if not cursor.execute("SHOW DATABASES LIKE 'datamaster'"): |
| 28 | return |
| 29 | |
| 30 | # Déterminons la liste de tables de référence dans datamaster |
| 31 | cursor.execute("SHOW TABLES IN datamaster LIKE 'ref\\_%%'") |
| 32 | datamaster_tables = set(row[0] for row in cursor) |
| 33 | |
| 34 | # Déterminons la liste de tables que nous avons déjà et |
| 35 | # enlevons-les des tables de datamaster |
| 36 | cursor.execute("SHOW FULL TABLES WHERE Table_type != 'VIEW'") |
| 37 | my_tables = set(row[0] for row in cursor) |
| 38 | datamaster_tables.difference_update(my_tables) |
| 39 | |
| 40 | # On peut maintenant créer les vues |
| 41 | if verbosity > 0: |
| 42 | print "Création des vues vers datamaster" |
| 43 | for table in datamaster_tables: |
| 44 | if verbosity > 1: |
| 45 | print "Création d'une vue vers datamaster.%s" % table |
| 46 | cursor.execute( |
| 47 | 'CREATE OR REPLACE VIEW `%s` AS SELECT * FROM datamaster.`%s`' % |
| 48 | (table, table) |
| 49 | ) |
| 50 | |
| 51 | |
| 52 | @receiver(post_syncdb) |
| 53 | def supprimer_cles_etrangeres(sender, **kwargs): |
| 54 | """ |
| 55 | Supprime les contraintes de clé étrangère qui pointent vers les vues de |
| 56 | datamaster. |
| 57 | """ |
| 58 | verbosity = kwargs.get('verbosity', 1) |
| 59 | |
| 60 | # Tout ça ne s'applique qu'à des BDs MySQL. L'attribut |
| 61 | # db.connection.vendor n'est présent qu'à partir de Django 1.3 |
| 62 | if (hasattr(db.connection, 'vendor') |
| 63 | and db.connection.vendor != 'mysql') or \ |
| 64 | 'mysql' not in db.backend.__name__: |
| 65 | return |
| 66 | |
| 67 | # Cherchons toute foreign key qui pointe vers une vue d'une table de |
| 68 | # référence. |
| 69 | cursor = db.connection.cursor() |
| 70 | cursor.execute( |
| 71 | """ |
| 72 | SELECT c.CONSTRAINT_SCHEMA, c.TABLE_NAME, c.CONSTRAINT_NAME |
| 73 | FROM |
| 74 | information_schema.REFERENTIAL_CONSTRAINTS c |
| 75 | INNER JOIN information_schema.VIEWS v |
| 76 | ON v.TABLE_SCHEMA = c.CONSTRAINT_SCHEMA |
| 77 | AND v.TABLE_NAME = c.REFERENCED_TABLE_NAME |
| 78 | WHERE c.REFERENCED_TABLE_NAME LIKE 'ref\\_%%' |
| 79 | """ |
| 80 | ) |
| 81 | for schema, table, constraint in cursor: |
| 82 | if verbosity > 0: |
| 83 | print "Suppression de la contrainte %s sur la table %s.%s..." % ( |
| 84 | constraint, schema, table |
| 85 | ) |
| 86 | db.connection.cursor().execute( |
| 87 | 'ALTER TABLE `%s`.`%s` DROP FOREIGN KEY `%s`' % |
| 88 | (schema, table, constraint) |
| 89 | ) |
| 90 | |
| 91 | # Supprimer les clés étrangères aussi après un migrate |
| 92 | try: |
| 93 | from south.signals import post_migrate |
| 94 | except ImportError: |
| 95 | pass |
| 96 | else: |
| 97 | post_migrate.connect(supprimer_cles_etrangeres) |