PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Schémas PostgreSQL / Espaces de noms avec Django

Et si vous pouviez organiser vos objets de base de données (par exemple, des tables et des vues) dans des espaces de noms en fonction de leurs rôles dans le système ?
Dans cet article, nous verrons la bonne façon de gérer les schémas PostgreSQL dans Django et quelques petits conseils sur Modèles Django et Python.

Schéma

Également connu sous le nom d'espace de noms, le schéma est un type d'objet de base de données dont le but est d'être une couche d'organisation hiérarchique située juste en dessous d'une base de données.
Sur PostgreSQL, "public" est le schéma par défaut, mais vous pouvez créer le vôtre des espaces de noms pour organiser d'autres objets de type tels que des tables, des vues, des fonctions, etc.

Hiérarchie des objets de la base de données

- Server
   |- PostgreSQL Instance (Port 5432 by default)
       |- Role (Users and Groups)
       |- Tablespace
       |- Database
           |- Trigger
           |- Extension
           |- Language
           |- Schema      
               |- Table
               |- View
               |- Materialized View
               |- Sequence
               |- Function
               |- Procedure

À propos de notre laboratoire

C'est un laboratoire simple avec Django dans un environnement virtuel (avec virtualenv) et PostgreSQL installé dans localhost.

  • Python 3.8
  • Django 3.0
  • PostgreSQL 12

Devrait fonctionner avec de nombreuses versions plus anciennes 🙂

Codes

  • > SQL (psql) ;
  • shell $ (Linux, FreeBSD, Unix*) ;
  • >>> Shell Python.

Pratiquer

  • PostgreSQL

La structure de la base de données est la première chose que nous allons faire.

  • Création de l'utilisateur de la base de données pour l'application ;
  • Création de base de données ;
  • Création de schéma ;
  • Création de tableaux

Créons notre propre exemple dans l'outil de ligne de commande intégré psql :

$ psql

Création de l'application utilisateur :

CREATE ROLE user_test ENCRYPTED PASSWORD '123' LOGIN;

Le rôle de base de données a été créé avec un mot de passe chiffré et un attribut de connexion (utilisateur).

Création de la base de données pour les tests :

> CREATE DATABASE db_test OWNER user_test;

La base de données appartient à "user_test".

Connectez-vous-y en tant qu'utilisateur "user_test":

> \c db_test user_test

À l'intérieur du psql shell \c nom d'utilisateur de la base de données.

Création d'un schéma :

> CREATE SCHEMA ns_hr;

L'espace de noms de notre exemple est prêt !

Afficher tous les schémas qui ne sont pas des catalogues :

> SELECT
nspname AS namespace
FROM pg_catalog.pg_namespace
WHERE nspname !~ '(^pg_|information_schema)';

Sortie :

namespace 
-----------
 public
 ns_hr

Notez qu'apparaît l'espace de noms par défaut (public) et le ns_hr, créé pour notre laboratoire.

Création d'une table dans le schéma ns_hr :

> CREATE TABLE ns_hr.tb_person(
    id_ serial primary key,
    name text not null,
    surname text not null
);

Un tableau simple…

Appuyez sur <Ctrl> + D pour quitter.

  • Django

Il est temps de coder en Python ! 😀

  • Environnement virtuel ;
  • Installation de modules Python ;
  • Création et configuration du projet Django ;
  • Création de l'application Django ;
  • Création d'un modèle Django ;
  • Migration ;
  • Tests dans le shell ;

Création d'environnement virtuel :

$ virtualenv -p `which python3.8` django

Le chemin absolu du binaire de Python 3.8 a été indiqué comme interpréteur Python de cet environnement.

Accédez au répertoire de l'environnement et activez-le :

$ cd django && source bin/activate

Votre invite a changé, commençant à "(django)" indiquant que votre environnement virtuel était activé.

Installez les modules nécessaires pour nos tests :

$ pip install django psycopg2-binary configobj ipython

Respectivement :Framework Web Django, pilote PostgreSQL, lecteur de fichier de configuration et shell interactif amélioré.

Création d'un nouveau projet Django :

$ django-admin startproject my_project

Renommer le répertoire du projet en src :

$ mv my_project src

Ceci est pour faciliter la hiérarchie des répertoires et n'affectera pas les résultats. C'est parce que cela a un répertoire de même nom qui peut prêter à confusion…

Création du fichier de configuration de la base de données :

$ cat << EOF > src/my_project/db.conf
DB_HOST = 'localhost'
DB_NAME = 'db_test'
DB_USER = 'user_test'
DB_PASSWORD = '123'
DB_PORT = 5432
EOF

Ici, nous avons créé un fichier de configuration séparé pour la connexion à la base de données.

Modifiez le fichier de configuration principal du projet :

$ vim src/my_project/settings.py

import os

from configobj import ConfigObj

Sous les importations, ajoutez une ligne qui apporte la classe ConfigObj.

# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

# Database configuration file location
DB_CONF_FILE = f'{BASE_DIR}/my_project/db.conf'

# Read the configurations from file
DB_CONFIG = ConfigObj(DB_CONF_FILE)

# Database connection parameters

DB_HOST = DB_CONFIG['DB_HOST']
DB_NAME = DB_CONFIG['DB_NAME']
DB_USER = DB_CONFIG['DB_USER']
DB_PASSWORD = DB_CONFIG['DB_PASSWORD']
DB_PORT = DB_CONFIG['DB_PORT']

DATABASES = {
             'default': {
                         'ENGINE': 'django.db.backends.postgresql',
                         'NAME': DB_NAME,
                         'USER': DB_USER,
                         'PASSWORD': DB_PASSWORD,
                         'HOST': DB_HOST,
                         'PORT': DB_PORT,
                         }
            }

Modifiez la "session" de la base de données comme ci-dessus.

Création d'un lien symbolique pour manage.py :

$ ln -s `pwd`/src/manage.py `pwd`/bin/manage.py

Pour faciliter notre travail, nous avons créé un lien symbolique vers manage.py dans le répertoire bin qui se trouve dans notre $PATH.

Exécutez le serveur Web virtuel :

$ manage.py runserver 0.0.0.0:8000

Testez dans votre navigateur :http://localhost:8000 puis + C pour abandonner.

Accéder au répertoire du projet :

$ cd src

Vérifions les fichiers dans le répertoire actuel :

$ tree .

Sortie :

.
├── manage.py
└── my_project
    ├── db.conf
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-38.pyc
    │   ├── settings.cpython-38.pyc
    │   ├── urls.cpython-38.pyc
    │   └── wsgi.cpython-38.pyc
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Liste le contenu du répertoire courant dans un format arborescent.
Ici, nous voyons tous les fichiers à l'intérieur du projet.

Première migration pour les métadonnées Django :

$ manage.py migrate

Création du super utilisateur de Django :

$ manage.py createsuperuser

Créer une application :

$ manage.py startapp human_resource

Modifiez settings.py pour ajouter une nouvelle application :

$ vim my_project/settings.py
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Custom Apps
    'human_resource',
]

Une astuce sympa de Django :vous pouvez utiliser un répertoire models au lieu d'un fichier models.py.
Mais vous devez créer un fichier init dunder (__init__.py) dans le répertoire models.
Allons-y !

Création d'un répertoire de modèles dans le répertoire de l'application :

$ mkdir human_resource/models

Supprimez le fichier models.py :

$ rm -f human_resource/models.py

Création du modèle :

$ vim human_resource/models/hr.py
from django.db.models import AutoField
from django.db.models import Model
from django.db.models import TextField


class Person(Model):
    '''
    Person Model

    Namespace: ns_hr
    Table: tb_person
    '''

    id_ = AutoField(db_column='id_', name='id', primary_key=True,)
    name = TextField(db_column='name', name='name',)
    surname = TextField(db_column='surname', name='surname',)

    def __str__(self):
        return f'{self.name} {self.surname}'

    class Meta:
        db_table = 'ns_hr"."tb_person'  # 'schema"."object'
        verbose_name_plural = 'Person'

Pour profiter des avantages des schémas PostgreSQL, à l'intérieur de votre modèle, dans la classe interne Meta, à la valeur de l'attribut "db_table", vous devez mettre un point qui sépare l'espace de noms et l'objet entre guillemets.

'schema"."object'

L'objet peut être une table ou une vue, par exemple…

Dunder init dans le répertoire des modèles pour que les migrations prennent effet :

vim human_resource/models/__init__.py
from human_resource.models.hr import Person

Ceci est nécessaire pour que le répertoire des modèles fonctionne comme un fichier models.py.

(Non) migrations :ma base de données, mes règles !

Nous créons la structure de notre base de données et aucun ORM ne devrait le faire pour nous !
Nous avons le pouvoir !
Nous avons la puissance !
Nous sommes aux commandes !

Notre base de données, nos règles ! 😉

Modélisez simplement votre base de données de vos propres mains et faites une fausse migration Django.
Parce que nous seuls savons comment les objets de la base de données doivent être créés 😉

Effectuer des migrations pour l'application human_resource :

$ manage.py makemigrations human_resource

Fausse migration :

$ manage.py migrate --fake

Vérifions la hiérarchie des répertoires de l'application :

$ tree human_resource/
human_resource/
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│   ├── 0001_initial.py
│   ├── __init__.py
│   └── __pycache__
│       ├── 0001_initial.cpython-38.pyc
│       └── __init__.cpython-38.pyc
├── models
│   ├── hr.py
│   ├── __init__.py
│   └── __pycache__
│       ├── hr.cpython-38.pyc
│       └── __init__.cpython-38.pyc
├── __pycache__
│   ├── admin.cpython-38.pyc
│   └── __init__.cpython-38.pyc
├── tests.py
└── views.py

Django Shell (Ipython) :

$ manage.py shell
>>> from human_resource.models.hr import Person

>>> p = Person(name='Ludwig', surname='van Beethoven')                                                                         

>>> print(p)

Sortie :

Ludwig van Beethoven
>>> p.save()   # Persist in database

Appuyez sur <Ctrl> + D pour sortir !

Shell de base de données (psql) :

$ manage.py dbshell

Une requête pour vérifier si les données ont été insérées par Django :

>  SELECT id_, name, surname FROM ns_hr.tb_person;

Sortie :

 id |  name  |    surname    
----+--------+---------------
  1 | Ludwig | van Beethoven

Conclusion

PostgreSQL est un SGBDR robuste et puissant avec de nombreuses fonctionnalités, y compris des espaces de noms pour ses objets.
Django est un excellent framework Web qui est très robuste et possède également de nombreuses fonctionnalités.
Ainsi, vous pouvez extraire le meilleur des deux pour obtenir de meilleurs résultats et pour ce faire, l'un des moyens est d'obtenir une meilleure organisation.
L'organisation de vos objets de base de données dans des espaces de noms en fonction de leurs rôles vous apportera des avantages 😉