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
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 😉