sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLスキーマ/Djangoを使用した名前空間

    システムでの役割に応じてデータベースオブジェクト(テーブルやビューなど)を名前空間に整理できるとしたらどうでしょうか?
    この記事では、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次に、+Cで中止します。

    プロジェクトディレクトリにアクセスする:

    $ 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つの方法は、より良い編成を取得することです。
    データベースオブジェクトをその役割に従って名前空間に編成すると、メリットがもたらされます😉


    1. 外部キーがある場合とない場合の参照の違いは何ですか

    2. Oracleのvarchar値に含まれる文字の出現回数をカウントするにはどうすればよいですか?

    3. MySQL-選択時に行番号を取得

    4. MySQLのロックの粒度を理解する