Wie wäre es, wenn Sie Ihre Datenbankobjekte (z. B. Tabellen und Ansichten) entsprechend ihrer Rollen im System in Namespaces organisieren könnten?
In diesem Artikel sehen wir den richtigen Umgang mit PostgreSQL-Schemas in Django und einige kleine Tipps dazu Django-Modelle und Python.
Schema
Auch als Namespace bekannt, ist ein Schema ein Typ von Datenbankobjekt, dessen Zweck es ist, eine hierarchische Organisationsebene zu sein, die sich direkt unter einer Datenbank befindet.
Bei PostgreSQL ist „öffentlich“ das Standardschema, aber Sie können Ihr eigenes Schema erstellen Namespaces zum Organisieren von Objekten anderer Art wie Tabellen, Ansichten, Funktionen usw.
Hierarchie der Datenbankobjekte
- Server |- PostgreSQL Instance (Port 5432 by default) |- Role (Users and Groups) |- Tablespace |- Database |- Trigger |- Extension |- Language |- Schema |- Table |- View |- Materialized View |- Sequence |- Function |- Procedure
Über unser Labor
Das ist ein einfaches Lab mit Django in einer virtuellen Umgebung (mit virtualenv) und PostgreSQL, das auf localhost installiert ist.
- Python 3.8
- Django 3.0
- PostgreSQL 12
Sollte mit vielen älteren Versionen funktionieren 🙂
Codes
- > SQL (psql);
- $-Shell (Linux, FreeBSD, Unix*);
- >>> Python-Shell.
Üben
-
PostgreSQL
Die Datenbankstruktur ist das erste, was wir tun werden.
- Erstellen eines Datenbankbenutzers für die Anwendung;
- Datenbankerstellung;
- Schemaerstellung;
- Tabellenerstellung
Lassen Sie uns unser eigenes Beispiel im eingebauten psql-Befehlszeilentool erstellen:
$ psql
Erstellung der Benutzeranwendung:
CREATE ROLE user_test ENCRYPTED PASSWORD '123' LOGIN;
Die Datenbankrolle wurde mit einem verschlüsselten Passwort und Anmeldeattribut (Benutzer) erstellt.
Erstellung einer Datenbank für Tests:
> CREATE DATABASE db_test OWNER user_test;
Die Datenbank gehört „user_test“.
Verbinden Sie sich als Benutzer „user_test“:
> \c db_test user_test
Innerhalb der psql-Shell \c Datenbank-Benutzername.
Erstellung eines Schemas:
> CREATE SCHEMA ns_hr;
Der Namensraum für unser Beispiel ist fertig!
Alle Schemas anzeigen, die keine Kataloge sind:
> SELECT nspname AS namespace FROM pg_catalog.pg_namespace WHERE nspname !~ '(^pg_|information_schema)';
Ausgabe:
namespace ----------- public ns_hr
Beachten Sie, dass der Standard-Namespace (öffentlich) und das für unser Lab erstellte ns_hr erscheinen.
Erstellung einer Tabelle im Schema ns_hr:
> CREATE TABLE ns_hr.tb_person( id_ serial primary key, name text not null, surname text not null );
Eine einfache Tabelle…
Drücken Sie <Ctrl> + D
zum Beenden.
-
Django
Es ist Zeit, in Python zu programmieren! 😀
- Virtuelle Umgebung;
- Installation von Python-Modulen;
- Erstellung und Konfiguration von Django-Projekten;
- Django-App-Erstellung;
- Django-Modellerstellung;
- Migrationen;
- Tests in der Shell;
Erstellung einer virtuellen Umgebung:
$ virtualenv -p `which python3.8` django
Der absolute Pfad der Binärdatei von Python 3.8 wurde als Python-Interpreter dieser Umgebung angegeben.
Greifen Sie auf das Umgebungsverzeichnis zu und aktivieren Sie es:
$ cd django && source bin/activate
Ihre Eingabeaufforderung hat sich geändert, sie begann mit „(django)“, was darauf hinweist, dass Ihre virtuelle Umgebung aktiviert wurde.
Installieren Sie die für unsere Tests erforderlichen Module:
$ pip install django psycopg2-binary configobj ipython
Jeweils:Django-Webframework, PostgreSQL-Treiber, Konfigurationsdatei-Reader und verbesserte interaktive Shell.
Erstellung eines neuen Django-Projekts:
$ django-admin startproject my_project
Benennen Sie das Verzeichnis des Projekts in src:um
$ mv my_project src
Dies dient der Vereinfachung der Verzeichnishierarchie und wirkt sich nicht auf die Ergebnisse aus. Das liegt daran, dass es ein gleichnamiges Verzeichnis hat, das einige Verwirrung stiften kann …
Erstellung der Datenbankkonfigurationsdatei:
$ 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
Hier haben wir eine separate Konfigurationsdatei für die Datenbankverbindung erstellt.
Bearbeiten Sie die Hauptkonfigurationsdatei des Projekts:
$ vim src/my_project/settings.py
import os from configobj import ConfigObj
Fügen Sie unter den Imports eine Zeile hinzu, die die Klasse ConfigObj bringt.
# 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, } }
Ändern Sie die „Sitzung“ der Datenbank wie oben beschrieben.
Symbolische Linkerstellung für manage.py:
$ ln -s `pwd`/src/manage.py `pwd`/bin/manage.py
Um unsere Arbeit zu erleichtern, haben wir einen symbolischen Link zu manage.py im bin-Verzeichnis erstellt, das sich in unserem $PATH.
befindet
Virtuellen Webserver ausführen:
$ manage.py runserver 0.0.0.0:8000
Testen Sie in Ihrem Browser:http://localhost:8000 und dann
Auf Projektverzeichnis zugreifen:
$ cd src
Überprüfen wir die Dateien im aktuellen Verzeichnis:
$ tree .
Ausgabe:
. ├── 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
Listet den Inhalt des aktuellen Verzeichnisses in einem baumähnlichen Format auf.
Hier sehen wir alle Dateien innerhalb des Projekts.
Erste Migration für Django-Metadaten:
$ manage.py migrate
Erstellung eines Superusers von Django:
$ manage.py createsuperuser
App erstellen:
$ manage.py startapp human_resource
Settings.py bearbeiten, um neue App hinzuzufügen:
$ 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', ]
Ein cooler Django-Trick:Sie können statt einer Datei models.py auch ein Verzeichnis models verwenden.
Aber Sie müssen eine Dunder-Init-Datei (__init__.py) im Models-Verzeichnis erstellen.
Los geht's!
Erstellung des Modellverzeichnisses im App-Verzeichnis:
$ mkdir human_resource/models
Entfernen Sie die Datei "models.py":
$ rm -f human_resource/models.py
Modellerstellung:
$ 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'
Um die Vorteile von PostgreSQL-Schemas nutzen zu können, müssen Sie innerhalb Ihres Modells in der inneren Klasse Meta zum Wert des Attributs „db_table“ einen Punkt setzen, der Namespace und Objekt zwischen Anführungszeichen trennt.
'schema"."object'
Das Objekt könnte zum Beispiel eine Tabelle oder eine Ansicht sein…
Dunder init im Modellverzeichnis, damit die Migrationen wirksam werden:
vim human_resource/models/__init__.py
from human_resource.models.hr import Person
Dies ist notwendig, damit das Modellverzeichnis als Datei "models.py" funktioniert.
(Keine) Migrationen:Meine Datenbank, meine Regeln!
Wir erstellen die Struktur unserer Datenbank und kein ORM sollte das für uns tun!
Wir haben die Macht!
Wir haben die Macht!
Wir haben das Kommando!
Unsere Datenbank, unsere Regeln! 😉
Modellieren Sie Ihre Datenbank einfach selbst und führen Sie eine gefälschte Django-Migration durch.
Denn nur wir wissen, wie die Datenbankobjekte erstellt werden müssen 😉
Migrationen für die human_resource-App durchführen:
$ manage.py makemigrations human_resource
Gefälschte Migration:
$ manage.py migrate --fake
Überprüfen wir die Verzeichnishierarchie der App:
$ 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)
Ausgabe:
Ludwig van Beethoven
>>> p.save() # Persist in database
Drücken Sie <Ctrl> + D
zum Beenden!
Datenbank-Shell (psql):
$ manage.py dbshell
Eine Abfrage, um zu prüfen, ob die Daten von Django eingefügt wurden:
> SELECT id_, name, surname FROM ns_hr.tb_person;
Ausgabe:
id | name | surname ----+--------+--------------- 1 | Ludwig | van Beethoven
Schlussfolgerung
PostgreSQL ist ein robustes und leistungsstarkes RDBMS mit vielen Funktionen, einschließlich Namensräumen für seine Objekte.
Django ist ein großartiges Web-Framework, das sehr robust ist und auch viele Funktionen hat.
Sie können es also Extrahieren Sie das Beste aus beiden, um bessere Ergebnisse zu erzielen, und um dies zu erreichen, ist eine der Möglichkeiten, eine bessere Organisation zu erreichen.
Die Organisation Ihrer Datenbankobjekte in Namespaces entsprechend ihren Rollen wird Ihnen Vorteile bringen 😉