LoginSignup
0
1

DjangoでDB接続・操作

Last updated at Posted at 2024-01-16

ORM (Object-Relational Mapping)

データベースとオブジェクト指向プログラミング言語の間の非互換なデータを変換するプログラミング技法である
コード-> ORM -> DB connection module -> DB

install DB connection module

postgreSql

pip install psycopg[binary]

django側の設定

  • ファイルを作成
    • .pg_service.conf
      • windowsの場合、%APPDATA%\Roaming\postgresqlで作成する
      • linuxの場合、Homeディレクトリ
    • .my_pgpass Djangoのプロジェクト・ディレクトリ

ファイルの内容

  • .pg_service.conf
[db_service]
host=localhost
user=USER_NAME
dbname=DB_NAME
port=5432
  • .my_pgpass
localhost:5432:DB_NAME:USER_NAME:PASSWORD

(ORM) DB操作

app/models.pyでクラスの編集によってデーブルを操作する

Create table

from django.db import models

class Offices(models.Model):
    office_name = models.CharField(max_length=32)
    isDeleted = models.BooleanField(default=False)

    class Meta:
        db_table = 'offices' #テーブルの名前

ここで、一個のクラスが一個のテーブルに対応している。
クラスを作成してから、manage.pymakemigrationsを実行して、miragteを行うと、DBに変更を書き込む。
Primary Keyを指定していない場合、idという列のをPrimary Keyとして自動的作ってくれる。
データ追加するとき、そのidの値が自動的に生成する。

以下でいうmigrateとは、manage.pymakemigrationsしてから、migrateを行う操作です。

Delete table

models.pyでそのテーブルに対応しているクラスを注釈にして、migrateすると、DBにあるテーブルを削除できる。

列の削除

同じく、テーブルで列を削除したい場合、クラスで新しいfieldを追加し、migrateするとDBが変更される。

列の追加

しかし、デーブルに列を追加したい場合、下記の警告が出る。これは、新しく追加された列で既存の行の値が決まっていないからです。

It is impossible to add a non-nullable field 'office_id' to offices without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit and manually define a default value in models.py.

そこで、二つの選択肢がある。

  • 1) を選択した場合、値をその場で入力する。
  • 2)を選択した場合、デフォルトの値をmodels.pyで決める。(default=<?>か、null=True, blank=Trueなどを入れる)

Foreign Keyの設定

参照元:部門テーブル

class Group(models.Model):
    group_id = models.IntegerField(primary_key=True)
    group_name = models.CharField(max_length=32, help_text='部門名')
    # Foreign Key を設定
    department = models.ForeignKey(Department, on_delete=models.CASCADE)

参照先:部署テーブル

class Department(models.Model):
    department_id = models.IntegerField(primary_key=True, help_text='部署ID')
    department_name = models.CharField(max_length=32, help_text='部署名')

ここで、部署と部門は一対多の関係である。

on_deleteの設定

外部キーで参照先テーブルを削除された場合の挙動を設定する

  • CASCADE:参照先デーブルが削除されたら、参照元テーブルも削除される。
  • PROTECT:参照元のデータが全部削除されていない限り、参照先のテーブルを削除できない

(ORM) データ操作

Create

クラス.objects.createでデータを追加する
Offices.objects.create(office_id=1, office_name='本社', isDeleted=False) ,
SQLのinsert into offices (office_id, office_name, isDeleted) values (1, '本社', False)と等しい

Delete

  • 特定のレコードを削除:クラス.objects.filter(id=3).delete()
  • 全てのレコードを削除:クラス.objects.all().delete()

Select

クラス.objects.all()
クラス.objects.filter(id=1)
戻り値はQuerySet型のListで、Listの各要素がデーブルの一行をObjectとして格納している。

戻り値が一行しかない場合、クラス.objects.filter(id=1).first() でその行のObjectを返却させる

first()は最初の行のObjectを返す

Update

全てをUpdate:クラス.objects.all().update(列=値)
特定のレコードをUpdate:クラス.objects.filter(id=1).update(列=値)

Admin.pyでテーブルのmodelsを登録

Appのadmin.pyで下記のように記載する:

from App.models import オブジェクト
admin.site.register(modelsオブジェクト)

そして、manage.pycreatesuperuserをし、管理者アカウントを作成し、runserverすると、テーブルをadminページで管理できるようになる。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1