E se potessi organizzare gli oggetti del tuo database (ad es. tabelle e viste) in spazi dei nomi in base ai suoi ruoli nel sistema?
In questo articolo vedremo il modo corretto di gestire gli schemi PostgreSQL in Django e alcuni piccoli suggerimenti su Modelli Django e Python.
Schema
Conosciuto anche come spazio dei nomi, lo schema è un tipo di oggetto database il cui scopo è quello di essere un livello organizzativo gerarchico che si trova appena sotto un database.
Su PostgreSQL, "pubblico" è lo schema predefinito, ma puoi crearne uno tuo namespace per organizzare altri tipi di oggetti come tabelle, viste, funzioni e così via
Gerarchia degli oggetti del database
- Server |- Istanza PostgreSQL (porta 5432 per impostazione predefinita) |- Ruolo (Utenti e gruppi) |- Tablespace |- Database |- Trigger |- Estensione |- Lingua |- Schema |- Tabella |- Visualizza |- Materializzato Visualizza |- Sequenza |- Funzione |- Procedura
Informazioni sul nostro laboratorio
È un semplice lab con Django in un ambiente virtuale (con virtualenv) e PostgreSQL installato in localhost.
- Python 3.8
- Django 3.0
- PostgreSQL 12
Dovrebbe funzionare con molte versioni precedenti 🙂
Codici
- > SQL (psql);
- $ shell (Linux, FreeBSD, Unix*);
- >>> Shell Python.
Esercitati
-
PostgreSQL
La struttura del database è la prima cosa che faremo.
- Creazione dell'utente del database per l'applicazione;
- Creazione database;
- Creazione dello schema;
- Creazione tabella
Creiamo il nostro esempio nello strumento da riga di comando integrato di psql:
$ psql
Creazione dell'applicazione utente:
CREA RUOLO user_test PASSWORD CRIPTATA '123' LOGIN;
Il ruolo del database è stato creato con una password crittografata e un attributo di accesso (utente).
Creazione database per test:
> CREA DATABASE db_test PROPRIETARIO user_test;
Il database è di proprietà di “user_test”.
Connettiti ad esso come utente "user_test":
> \c db_test test_utente
All'interno della shell di psql \c nome utente del database.
Creazione di uno schema:
> CREA SCHEMA ns_hr;
Lo spazio dei nomi per il nostro esempio è pronto!
Mostra tutti gli schemi che non sono cataloghi:
> SELECTnspname AS namespaceFROM pg_catalog.pg_namespaceWHERE nspname !~ '(^pg_|information_schema)';
Uscita:
spazio dei nomi ----------- public ns_hr
Si noti che appare lo spazio dei nomi predefinito (pubblico) e ns_hr, creato per il nostro lab.
Creazione di una tabella nello schema ns_hr:
> CREATE TABLE ns_hr.tb_person( id_ chiave primaria seriale, testo nome non nullo, testo cognome non nullo);
Un semplice tavolo…
Premi <Ctrl> + D
per uscire.
-
Django
È ora di programmare in Python! 😀
- Ambiente virtuale;
- Installazione moduli Python;
- Creazione e configurazione del progetto Django;
- Creazione dell'app Django;
- Creazione del modello Django;
- Migrazioni;
- Test in shell;
Creazione dell'ambiente virtuale:
$ virtualenv -p `che python3.8` django
Il percorso assoluto del binario di Python 3.8 è stato indicato come interprete Python di questo ambiente.
Accedi alla directory dell'ambiente e attivala:
$ cd django &&source bin/activate
Il tuo prompt è cambiato, è iniziato con "(django)" indicando che il tuo ambiente virtuale è stato attivato.
Installa i moduli necessari per i nostri test:
$ pip install django psycopg2-binary configobj ipython
Rispettivamente:framework web Django, driver PostgreSQL, lettore di file di configurazione e shell interattiva migliorata.
Creazione del nuovo progetto Django:
$ django-admin startproject mio_progetto
Rinomina la directory del progetto in src:
$ mv mio_progetto src
Questo serve per semplificare la gerarchia delle directory e non influirà sui risultati. È perché ha una directory con lo stesso nome che può causare confusione...
Creazione del file di configurazione del database:
$ cat <src/my_project/db.confDB_HOST ='localhost'DB_NAME ='db_test'DB_USER ='user_test'DB_PASSWORD ='123'DB_PORT =5432EOF
Qui abbiamo creato un file di configurazione separato per la connessione al database.
Modifica il file di configurazione principale del progetto:
$ vim src/mio_progetto/settings.py
import osfrom configobj import ConfigObj
Sotto le importazioni aggiungi una riga che porta la classe ConfigObj.
# Database# https://docs.djangoproject.com/en/2.2/ref/settings/#databases# Posizione del file di configurazione del databaseDB_CONF_FILE =f'{BASE_DIR}/my_project/db.conf'# Leggi le configurazioni da fileDB_CONFIG =ConfigObj(DB_CONF_FILE)# Parametri di connessione al databaseDB_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, } }
Modificare la “sessione” del database come sopra.
Creazione di link simbolici per manage.py:
$ ln -s `pwd`/src/manage.py `pwd`/bin/manage.py
Per facilitare il nostro lavoro abbiamo creato un collegamento simbolico a manage.py nella directory bin che si trova nel nostro $PATH.
Esegui server web virtuale:
$ manage.py runserver 0.0.0.0:8000
Prova nel tuo browser:http://localhost:8000 e poi
Accesso alla directory del progetto:
$ cd src
Controlliamo i file all'interno della directory corrente:
albero $ .
Uscita:
.├── manage.py└── mio_progetto ├── db.conf ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-38.pyc │ ├.── settings .pyc │ ├── urls.cpython-38.pyc │ └── wsgi.cpython-38.pyc ├── settings.py ├── urls.py └── wsgi.py
Elenca i contenuti della directory corrente in un formato ad albero.
Qui vediamo tutti i file all'interno del progetto.
Prima migrazione per i metadati di Django:
$ manage.py migra
Creazione del super utente di Django:
$ manage.py createsuperuser
Crea un'app:
$ manage.py startapp risorse_umane
Modifica settings.py per aggiungere una nuova app:
$ vim mio_progetto/settings.py
# Definizione dell'applicazioneINSTALLED_APPS =[ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django .contrib.staticfiles', # App personalizzate 'human_resource',]
Un bel trucco di Django:puoi usare una directory models invece di un file models.py.
Ma devi creare un file init dunder (__init__.py) all'interno della directory models.
Andiamo!
Creazione della directory dei modelli all'interno della directory dell'app:
$ mkdir risorse_umane/modelli
Rimuovi il file models.py:
$ rm -f risorse_umane/models.py
Creazione del modello:
$ vim human_resource/models/hr.py
from django.db.models import AutoFieldfrom django.db.models import Modelfrom django.db.models import TextFieldclass 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',) cognome =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 ='Persona'
Per godere dei vantaggi degli schemi PostgreSQL, all'interno del tuo modello, nella classe interna Meta, al valore dell'attributo "db_table" devi mettere un punto che separa lo spazio dei nomi e l'oggetto tra virgolette.
'schema"."object'
L'oggetto potrebbe essere una tabella o una vista, ad esempio...
Dunder init all'interno della directory models per le migrazioni ha effetto:
vim human_resource/models/__init__.py
da human_resource.models.hr import Person
Ciò è necessario perché la directory models funzioni come file models.py.
(No) Migrazioni:il mio database, le mie regole!
Creiamo la struttura del nostro database e nessun ORM dovrebbe farlo per noi!
Abbiamo il potere!
Abbiamo il potere!
Siamo al comando!
Il nostro database, le nostre regole! 😉
Basta modellare il tuo database con le tue mani ed eseguire una falsa migrazione Django.
Perché solo noi sappiamo come devono essere creati gli oggetti del database 😉
Esegui migrazioni per l'app risorse_umane:
$ manage.py makemigrations human_resource
Migrazione falsa:
$ manage.py migrate --fake
Controlliamo la gerarchia delle directory dell'app:
$ tree human_resource/
risorsa_umana/├── admin.py├── apps.py├── __init__.py├── migrazioni│ ├── 0001_initial.py│ ├── __init__.py│ ─── __pycaca 0001_initial.cpython-38.pyc│ └── __init__.cpython-38.pyc├── models│ ├── hr.py│ ├── __init__.py│ └── __pycache__│ ├── .pyc│ └── __init__.cpython-38.pyc├── __pycache__│ ├── admin.cpython-38.pyc│ └── __init__.cpython-38.pyc─── tests.py└─ py
Django Shell (Ipython):
$ shell di manage.py
>>> da human_resource.models.hr import Persona>>> p =Persona(nome='Ludwig', cognome='van Beethoven')>>> print(p)
Uscita:
Ludwig van Beethoven
>>> p.save() # Persiste nel database
Premi <Ctrl> + D
per uscire!
Shell del database (psql):
$ manage.py dbshell
Una query per verificare se i dati sono stati inseriti da Django:
> SELEZIONA id_, nome, cognome DA ns_hr.tb_person;
Uscita:
Conclusione
PostgreSQL è un RDBMS robusto e potente con molte funzionalità, inclusi gli spazi dei nomi per i suoi oggetti.
Django è un ottimo framework Web che è molto robusto e ha anche molte funzionalità.
Quindi, puoi estrarre il meglio da entrambi per ottenere risultati migliori e per farlo, uno dei modi è ottenere un'organizzazione migliore.
L'organizzazione degli oggetti del database negli spazi dei nomi in base ai suoi ruoli porterà vantaggi per te 😉