Multiple Koneksi Database Django Framework

Subscribe Dengan Account Google Untuk Membaca Artikel Tanpa Iklan
Multiple Koneksi Database Django Framework

Koneksi kedatabase menjadi suatu hal yang wajib untuk setiap aplikasi yang terhubung dengan basis data, sebuah framework yang menerapkan konsep ORM seharusnya mampu menangani pekerjaan multi koneksi database. Hal ini penting karena dalam pemrosesan data terkadang bagian data yang kita olah terpisah dengan database utama, beruntungnya django framework cukup mampu melakukan hal ini.

Bagaimana cara django framework mengatur multiple koneksi database ?


Langkah pertama untuk menggunakan lebih dari satu basis data dengan Django adalah memberi tahu Django tentang server basis data yang akan Anda gunakan. Ini dilakukan dengan menggunakan pengaturan DATABASES. Pengaturan ini memetakan alias basis data, yang merupakan cara untuk merujuk ke basis data tertentu di Django Framework.

Database dapat memiliki alias apa pun yang Anda pilih. Namun, alias default memiliki arti khusus. Django menggunakan database dengan alias default ketika tidak ada database lain yang dipilih.

perhatikan sample dibawah ini :

DATABASES = {
'default': {
'NAME': 'app_data',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'postgres_user',
'PASSWORD': 's3krit'
},
'users': {
'NAME': 'user_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'priv4te'
}
}

 

Jika konsep database default tidak sesuai dalam konteks proyek Anda, Anda harus berhati-hati untuk selalu menentukan database yang ingin Anda gunakan. Django mensyaratkan bahwa entri database default harus ditentukan, tetapi parameter ini dapat dibiarkan kosong jika tidak akan digunakan. Untuk melakukan ini, Anda harus menyiapkan DATABASE_ROUTERS untuk semua model aplikasi Anda, termasuk yang ada di kontrib dan aplikasi pihak ketiga apa pun yang Anda gunakan, sehingga tidak ada kueri yang dialihkan ke database default.

Perhatikan contoh dibawah ini :

DATABASES = {
'default': {},
'users': {
'NAME': 'user_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'superS3cret'
},
'customers': {
'NAME': 'customer_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_cust',
'PASSWORD': 'veryPriv@ate'
}
}

Menyinkronkan basis data Anda


Perintah manajemen migrasi beroperasi pada satu basis data pada satu waktu. Secara default, ini beroperasi pada database default, tetapi dengan menyediakan opsi --database, Anda dapat memerintahkannya untuk menyinkronkan database yang berbeda. Jadi, untuk menyinkronkan semua model ke semua basis data pada contoh pertama di atas, Anda perlu memanggil :

./manage.py migrate
./manage.py migrate --database=users

Jika Anda tidak ingin setiap aplikasi disinkronkan ke basis data tertentu, Anda dapat menentukan route basis data yang mengimplementasikan kebijakan yang membatasi ketersediaan model tertentu.

Jika, seperti dalam contoh kedua di atas, Anda membiarkan database default kosong, Anda harus memberikan nama database setiap kali Anda menjalankan migrasi. Mengabaikan nama basis data akan memunculkan kesalahan.

Perhatikan contoh dibawah ini:

./manage.py migrate --database=users
./manage.py migrate --database=customers

Database Routers


Router database adalah kelas yang menyediakan hingga empat metode:

  • db_for_read(model**hints)

  • db_for_write(model**hints)

  • allow_relation(obj1obj2**hints)

  • allow_migrate(dbapp_labelmodel_name=None**hints)


Perhatikan sample dibawah ini

DATABASES = {
'default': {},
'auth_db': {
'NAME': 'auth_db',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'swordfish',
},
'primary': {
'NAME': 'primary',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'spam',
},
'replica1': {
'NAME': 'replica1',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'eggs',
},
'replica2': {
'NAME': 'replica2',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'bacon',
},
}

class AuthRouter:
"""
A router to control all database operations on models in the
auth and contenttypes applications.
"""
route_app_labels = {'auth', 'contenttypes'}

def db_for_read(self, model, **hints):
"""
Attempts to read auth and contenttypes models go to auth_db.
"""
if model._meta.app_label in self.route_app_labels:
return 'auth_db'
return None

def db_for_write(self, model, **hints):
"""
Attempts to write auth and contenttypes models go to auth_db.
"""
if model._meta.app_label in self.route_app_labels:
return 'auth_db'
return None

def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the auth or contenttypes apps is
involved.
"""
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None

def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
Make sure the auth and contenttypes apps only appear in the
'auth_db' database.
"""
if app_label in self.route_app_labels:
return db == 'auth_db'
return None

import random

class PrimaryReplicaRouter:
def db_for_read(self, model, **hints):
"""
Reads go to a randomly-chosen replica.
"""
return random.choice(['replica1', 'replica2'])

def db_for_write(self, model, **hints):
"""
Writes always go to primary.
"""
return 'primary'

def allow_relation(self, obj1, obj2, **hints):
"""
Relations between objects are allowed if both objects are
in the primary/replica pool.
"""
db_list = ('primary', 'replica1', 'replica2')
if obj1._state.db in db_list and obj2._state.db in db_list:
return True
return None

def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
All non-auth models end up in this pool.
"""
return True

# This retrieval will be performed on the 'auth_db' database
fred = User.objects.get(username='fred')
fred.first_name = 'Frederick'

# This save will also be directed to 'auth_db'
fred.save()

These retrieval will be randomly allocated to a replica database
dna = Person.objects.get(name='Douglas Adams')

# A new object has no database allocation when created
mh = Book(title='Mostly Harmless')

# This assignment will consult the router, and set mh onto
# the same database as the author object
mh.author = dna

# This save will force the 'mh' instance onto the primary database...
mh.save()

# ... but if we re-retrieve the object, it will come back on a replica
mh = Book.objects.get(title='Mostly Harmless')

DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.PrimaryReplicaRouter']

 

baca artikel lainya :


sumber referensi : https://docs.djangoproject.com/en/3.0/