[PYTHON] J'ai fait une commande pour générer un commentaire pour une table dans Django

introduction

Django est pratique car il émet automatiquement une instruction Create Table à partir du modèle écrit dans models.py pour créer une table ... Cependant, il ne prend pas en charge le point où les commentaires sont ajoutés aux tables et colonnes. Si vous souhaitez générer à rebours le diagramme ER à partir de la table créée, j'apprécierais que vous ajoutiez un commentaire ...

Donc, s'il n'y en a pas, j'ai essayé de le faire moi-même.

Syntaxe des commentaires de table / colonne

La syntaxe pour ajouter des commentaires de table ou des commentaires de colonne est la suivante.

comment on table table_name is 'comment'
comment on column table_name.column_name is 'comment'

Cependant, il s'agit d'une spécification propriétaire d'Oracle et PostgreSQL (et DB2), et il semble que ce ne soit pas un standard SQL. J'aurais aimé pouvoir faire sqlite3 avec la même syntaxe si possible, mais j'ai abandonné cette fois parce que cela semble impossible. À tout le moins, j'aimerais faire un commentaire sur Oracle, que j'utilise habituellement.

Création de commandes personnalisées Django

Vous pouvez le créer comme un module Python normal, mais comme c'est un gros problème, créez votre propre commande Django afin de pouvoir l'exécuter rapidement à partir de la ligne de commande. Pour les commandes Django, en héritant de la classe AppCommand, vous pouvez recevoir l'objet AppConfig de l'application Django comme argument, il est donc facile d'obtenir une liste de modèles pour créer des commentaires.

Concernant la création de commandes personnalisées Django, je me suis référé à l'article suivant.

De plus, j'ai fait référence à la source de django.core.manegement.commands.sqlsequencereset.

Format de commande

Le nom de la commande est "créer un commentaire de table". Le format devrait ressembler à ↓.

manage.py createtablecomment [options] <app_label app_label ...>

Placement du module pour les commandes

Puisque la commande créée cette fois n'est pas pour une application spécifique, placez le module dans le dossier du projet. (Ce qui suit est une référence pour le placement. Le nom du projet est "mon projet")

myproject
 └ myproject
   └ management
     └ commands
       └ createtablecomment.py

Source de la classe de commande

Sauf pour le contenu de handle_app_config, je copie sqlsequencereset.py et je l'utilise presque tel quel.

createtablecomment.py


from __future__ import unicode_literals

from optparse import make_option

from django.core.management.base import AppCommand
from django.core.management.sql import check_for_migrations
from django.db import connections, DEFAULT_DB_ALIAS
from django.db.models.fields.related import ForeignKey

class Command(AppCommand):
    help = 'Prints the SQL statements for create comment of tables and columns for the given app name(s).'

    option_list = AppCommand.option_list + (
        make_option('--database', action='store', dest='database',
            default=DEFAULT_DB_ALIAS, help='Nominates a database to print the '
                'SQL for.  Defaults to the "default" database.'),
    )

    output_transaction = True

    def handle_app_config(self, app_config, **options):
        if app_config.models_module is None:
            return
        connection = connections[options.get('database')]
        check_for_migrations(app_config, connection)
        models = app_config.get_models(include_auto_created=True)
        cursor = connection.cursor()
        statements = []

        for model in models :
            statement = "COMMENT ON TABLE %s IS '%s'" %
                      (model._meta.db_table, model._meta.verbose_name)
            statements.append(statement)
            cursor.execute(statement)
            for field in model._meta.fields :
                if isinstance(field, ForeignKey) :
                    column  = '%s_id' % field.name
                    comment = '%s(FK:%s)' %
                            (field.verbose_name, field.related.parent_model._meta.db_table)
                else :
                    column  = '%s' % field.name
                    comment = field.verbose_name
                statement = "COMMENT ON COLUMN %s.%s IS '%s'" %
                          (model._meta.db_table, column, comment)
                statements.append(statement)
                cursor.execute(statement)
        return '\n'.join(statements)

Le contenu de traitement est comme ↓.

  1. Obtenez la liste des classes de modèles sous l'application avec ʻapp_config.get_models () `et tournez-la avec pour
  2. Créez et exécutez l'instruction create comment pour la table (récupérez le curseur avec connection.cursorl () etcursor.execute (instruction))
  3. Récupérez la liste des champs du modèle avec model._meta.fields et tournez-la avec pour
  4. Créez et exécutez l'instruction de création de commentaire pour la colonne (dans le cas du champ ForeignKey, complétez-le car" _id "est ajouté au nom de la colonne. Ajoutez également les informations" Quelle table est le FK? "
  5. Transformez la liste des instructions de commentaire de création exécutées en chaînes de caractères séparées par des sauts de ligne et un retour (lorsque la commande est exécutée depuis la console, l'instruction SQL exécutée est sortie vers la console)

Résultat d'exécution

J'ai essayé de l'exécuter pour l'application myapp qui a models.py de ↓.

models.py


from django.db import models

class Author(models.Model):
    class Meta :
        db_table = 'AUTHORS'
        verbose_name = 'Auteur'
        verbose_name_plural = verbose_name

    name = models.CharField('Nom', max_length=50)
    birthday = models.DateField('Anniversaire')

class BooK(models.Model):
    class Meta:
        verbose_name = 'Livre'
        verbose_name_plural = verbose_name

    name = models.CharField('Titre de livre', max_length=100)
    price = models.IntegerField('prix')
    author = models.ForeignKey(Author, verbose_name='Auteur')

Exécution de la commande

> python manage.py createtablecomment myapp
BEGIN;
COMMENT ON TABLE AUTHORS IS 'Auteur'
COMMENT ON COLUMN AUTHORS.id IS 'ID'
COMMENT ON COLUMN AUTHORS.name IS 'Nom'
COMMENT ON COLUMN AUTHORS.birthday IS 'Anniversaire'
COMMENT ON TABLE myapp_book IS 'Livre'
COMMENT ON COLUMN myapp_book.id IS 'ID'
COMMENT ON COLUMN myapp_book.name IS 'Titre de livre'
COMMENT ON COLUMN myapp_book.price IS 'prix'
COMMENT ON COLUMN myapp_book.author_id IS 'Auteur(FK:AUTHORS)'

COMMIT;

Les commentaires ont été créés avec succès sur les tables et les colonnes.

Recommended Posts

J'ai fait une commande pour générer un commentaire pour une table dans Django
J'ai créé un plugin pour générer une table Markdown à partir de csv avec Vim
J'ai fait une commande pour marquer le clip de la table
J'ai fait une commande pour afficher un calendrier coloré dans le terminal
J'ai fait un script pour mettre un extrait dans README.md
J'ai créé un module Python pour traduire les commentaires
J'ai créé une commande appdo pour exécuter des commandes dans le contexte de l'application
Comment générer une requête à l'aide de l'opérateur IN dans Django
J'ai fait une commande pour attendre que Django démarre jusqu'à ce que la base de données soit prête
Je vous ai fait exécuter des commandes depuis un navigateur WEB
J'ai créé un outil pour générer automatiquement un simple diagramme ER à partir de l'instruction CREATE TABLE
J'ai créé un programme de sortie de table de nombres premiers dans différentes langues
Je veux imprimer dans la notation d'inclusion
J'ai fait un programme de gestion de la paie en Python!
J'ai fait un script pour afficher des pictogrammes
J'ai fait une application WEB avec Django
[Django] a créé un champ pour saisir des dates avec des nombres à 4 chiffres
J'ai créé un outil CLI pour convertir les images de chaque répertoire en PDF
Je souhaite convertir une table convertie en PDF en Python en CSV
Ajout d'une fonction pour enregistrer les décalages souhaités dans la table des décalages Django
J'ai créé un script en python pour convertir des fichiers .md au format Scrapbox
J'ai fait un programme pour vérifier la taille d'un fichier avec Python
Notes J'ai recherché la création d'outils de ligne de commande en Python
Je veux corriger Datetime.now dans le test de Django
Je veux créer une fenêtre avec Python
J'ai créé un outil pour compiler nativement Hy
J'ai essayé de générer une chaîne de caractères aléatoire
J'ai créé un outil pour obtenir de nouveaux articles
Comment créer une API Rest dans Django
J'ai créé un programme cryptographique César en Python.
Je souhaite télécharger une application Django sur heroku
J'ai essayé de générer automatiquement une table de gestion des ports à partir de L2SW Config
J'ai fait un module en langage C qui filtre les images chargées par Python
J'ai créé un outil pour générer du Markdown à partir du fichier JSON Scrapbox exporté
〇✕ J'ai fait un jeu
Je veux facilement implémenter le délai d'expiration en python
Je veux faire la transition avec un bouton sur le ballon
J'ai fait une bibliothèque pour bien séparer les phrases japonaises
Je veux écrire en Python! (2) Écrivons un test
J'ai essayé d'implémenter un pseudo pachislot en Python
J'ai créé un code pour convertir illustration2vec en modèle Keras
Je veux échantillonner au hasard un fichier avec Python
Je veux travailler avec un robot en python.
Comment afficher DataFrame sous forme de tableau dans Markdown
J'ai créé une bibliothèque python qui fait rouler le rang
Comment exécuter une commande à l'aide d'un sous-processus en Python
Comment référencer des fichiers statiques dans un projet Django
J'ai implémenté une commande de remplacement de type Vim dans Slackbot #Python
Je ne peux pas dormir tant que je n'ai pas construit un serveur !! (Introduction au serveur Python faite en un jour)
J'ai fait un jeu de frappe simple avec tkinter de Python
J'ai essayé d'implémenter un automate cellulaire unidimensionnel en Python
J'ai créé un script en Python pour convertir un fichier texte pour JSON (pour l'extrait d'utilisateur vscode)
J'ai créé un package pour filtrer les séries chronologiques avec python
Renommer les colonnes de table dans Django3