システムでの役割に応じてデータベースオブジェクト(テーブルやビューなど)を名前空間に整理できるとしたらどうでしょうか?
この記事では、DjangoでPostgreSQLスキーマを処理する正しい方法といくつかのヒントを紹介します。 DjangoモデルとPython。
スキーマ
名前空間とも呼ばれるスキーマは、データベースのすぐ下にある階層的な組織レイヤーを目的としたデータベースオブジェクトの一種です。
PostgreSQLでは、「public」がデフォルトのスキーマですが、独自のスキーマを作成できます。テーブル、ビュー、関数などの他の種類のオブジェクトを整理するための名前空間。
データベースオブジェクトの階層
- Server |- PostgreSQL Instance (Port 5432 by default) |- Role (Users and Groups) |- Tablespace |- Database |- Trigger |- Extension |- Language |- Schema |- Table |- View |- Materialized View |- Sequence |- Function |- Procedure
ラボについて
これは、仮想環境(virtualenvを使用)にDjangoを配置し、ローカルホストにPostgreSQLをインストールしたシンプルなラボです。
- Python 3.8
- Django 3.0
- PostgreSQL 12
多くの古いバージョンで動作するはずです🙂
コード
- > SQL(psql);
- $シェル(Linux、FreeBSD、Unix *);
- >>>Pythonシェル。
練習
-
PostgreSQL
データベース構造は、私たちが最初に行うことです。
- アプリケーションのデータベースユーザーの作成;
- データベースの作成;
- スキーマの作成;
- テーブルの作成
psql組み込みコマンドラインツールで独自の例を作成しましょう:
$ psql
ユーザーアプリケーションの作成:
CREATE ROLE user_test ENCRYPTED PASSWORD '123' LOGIN;
データベースの役割は、暗号化されたパスワードとログイン属性(ユーザー)を使用して作成されました。
テスト用のデータベースの作成:
> CREATE DATABASE db_test OWNER user_test;
データベースは「user_test」が所有しています。
ユーザー「user_test」として接続します:
> \c db_test user_test
psqlシェル\cデータベースのユーザー名の内部。
スキーマの作成:
> CREATE SCHEMA ns_hr;
この例の名前空間は準備ができています!
カタログではないすべてのスキーマを表示する:
> SELECT nspname AS namespace FROM pg_catalog.pg_namespace WHERE nspname !~ '(^pg_|information_schema)';
出力:
namespace ----------- public ns_hr
ラボ用に作成されたデフォルトの名前空間(public)とns_hrが表示されることに注意してください。
ns_hrスキーマでのテーブルの作成:
> CREATE TABLE ns_hr.tb_person( id_ serial primary key, name text not null, surname text not null );
シンプルなテーブル…
<Ctrl> + D
を押します 終了します。
-
Django
Pythonでコーディングする時が来ました! 😀
- 仮想環境;
- Pythonモジュールのインストール;
- Djangoプロジェクトの作成と構成;
- Djangoアプリの作成;
- Djangoモデルの作成;
- 移行;
- シェルでのテスト;
仮想環境の作成:
$ virtualenv -p `which python3.8` django
Python 3.8のバイナリの絶対パスは、この環境のPythonインタープリターとして示されました。
環境のディレクトリにアクセスしてアクティブ化します:
$ cd django && source bin/activate
プロンプトが変更され、「(django)」で始まり、仮想環境がアクティブ化されたことを示します。
テストに必要なモジュールをインストールします:
$ pip install django psycopg2-binary configobj ipython
敬意を表する:Django Webフレームワーク、PostgreSQLドライバー、構成ファイルリーダー、改良されたインタラクティブシェル。
新しいDjangoプロジェクトの作成:
$ django-admin startproject my_project
プロジェクトのディレクトリの名前をsrcに変更します:
$ mv my_project src
これはディレクトリ階層を容易にするためであり、結果には影響しません。これは、同じ名前のディレクトリがあり、混乱を招く可能性があるためです…
データベース構成ファイルの作成:
$ 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
ここでは、データベース接続用に個別の構成ファイルを作成しました。
プロジェクトのメイン構成ファイルを編集します:
$ vim src/my_project/settings.py
import os from configobj import ConfigObj
インポートの下に、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, } }
上記のようにデータベースの「セッション」を変更します。
manage.pyのシンボリックリンクの作成:
$ ln -s `pwd`/src/manage.py `pwd`/bin/manage.py
作業を容易にするために、$PATHにあるbinディレクトリにmanage.pyへのシンボリックリンクを作成しました。
仮想ウェブサーバーを実行する:
$ manage.py runserver 0.0.0.0:8000
ブラウザでテストします:http:// localhost:8000次に、
プロジェクトディレクトリにアクセスする:
$ cd src
現在のディレクトリ内のファイルを確認しましょう:
$ tree .
出力:
. ├── 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
現在のディレクトリの内容をツリーのような形式で一覧表示します。
ここに、プロジェクト内のすべてのファイルが表示されます。
Djangoメタデータの最初の移行:
$ manage.py migrate
Djangoのスーパーユーザーの作成:
$ manage.py createsuperuser
アプリを作成する:
$ manage.py startapp human_resource
settings.pyを編集して新しいアプリを追加します:
$ 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', ]
クールなDjangoのトリック:ファイルmodels.pyの代わりにディレクトリモデルを使用できます。
ただし、modelsディレクトリ内にdunder initファイル(__init __。py)を作成する必要があります。
行きましょう!
アプリディレクトリ内のモデルディレクトリの作成:
$ mkdir human_resource/models
models.pyファイルを削除します:
$ rm -f human_resource/models.py
モデルの作成:
$ 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'
モデル内のMeta内部クラスでPostgreSQLスキーマの利点を享受するには、「db_table」属性の値に対して、名前空間とオブジェクトを引用符で区切るドットを配置する必要があります。
'schema"."object'
オブジェクトは、たとえば、テーブルまたはビューである可能性があります…
モデルディレクトリ内のDunderinitは、移行が有効になります:
vim human_resource/models/__init__.py
from human_resource.models.hr import Person
これは、modelsディレクトリがmodels.pyファイルとして機能するために必要です。
(いいえ)移行:私のデータベース、私のルール!
私たちはデータベースの構造を作成しますが、ORMがそれを行うべきではありません!
私たちには力があります!
私たちには力があります!
私たちは指揮を執っています!
私たちのデータベース、私たちのルール! 😉
自分の手でデータベースをモデル化し、偽のDjango移行を行うだけです。
データベースオブジェクトの作成方法を知っているのは私たちだけだからです😉
human_resourceアプリの移行を行う:
$ manage.py makemigrations human_resource
偽の移行:
$ manage.py migrate --fake
アプリのディレクトリ階層を確認しましょう:
$ 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)
出力:
Ludwig van Beethoven
>>> p.save() # Persist in database
<Ctrl> + D
を押します 終了します!
データベースシェル(psql):
$ manage.py dbshell
データがDjangoによって挿入されたかどうかを確認するクエリ:
> SELECT id_, name, surname FROM ns_hr.tb_person;
出力:
id | name | surname ----+--------+--------------- 1 | Ludwig | van Beethoven
結論
PostgreSQLは、オブジェクトの名前付けを含む多くの機能を備えた堅牢で強力なRDBMSです。
Djangoは、非常に堅牢で多くの機能を備えた優れたWebフレームワークです。
つまり、次のことができます。より良い結果を達成するために両方のより良いものを抽出し、これを行うための1つの方法は、より良い編成を取得することです。
データベースオブジェクトをその役割に従って名前空間に編成すると、メリットがもたらされます😉