Panduan topik ini menggambarkan dukungan Django untuk interaksi dengan banyak basisdata. Kebanyakan dari sisa dokumentasi Djangomenganggap anda berinteraksi dengan basisdata tunggal. Jika anda ingin berinteraksi dengan banyak basisdata, anda akan butuh mengambil beberapa langkah-langkah tambahan.
Lihat juga
Lihat Dukungan banyak-basisdata untuk informasi tentang percobaan dengan banyak basisdata.
Langkah pertama untuk menggunakan lebih dari satu basisdata dengan Django adalah memberitahu Django tentang peladen basisdata anda akan gunakan. Ini dilakukan menggunakan pengaturan DATABASES
. Pengaturan ini memetakan nama lain basisdata, yang adalah cara mengacu ke basisdata tertentu sepanjang Django, ke sebuah kamus dari pengaturan untuk hubungan tertentu itu. Pengaturan di sebelah dalam kamus digambarkan sepenuhnya dalam dokumentasi DATABASES
.
Basisdata dapat mempunyai nama lain apapun anda pilih. Bagaimanapun, nama lain default
mempunyai makna khusus. Django menggunakan basisdata dengan nama lain dari default
ketika tidak ada lagi basisdata telah dipilih.
Berikut adalah sebuah contoh potongan settings.py
menentukan dua basisdata -- sebuah awalan basisdata PostgreSQL dan basisdata MySQL disebut users
:
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 dari basisdata default
tidak masuk akal dalam konteks proyek anda, anda butuh berhati-hati untuk selalu menentukan basisdata anda ingin gunakan. Django membutuhkan masukan basisdata default
untuk ditentukan, tetapi parameter dictionary dapat berupa kosong jika itu akan tidak digunakan. Untuk melakkukan ini, anda harus menyetel DATABASE_ROUTERS
untuk semua dari model aplikasi anda, termasuk itu dalam bantuan dan aplikasi pihak-ketiga apapun anda sedang gunakan, sehingga tidak ada permintaan ke basisdata awalan. Berikut adalah contoh potongan settings.py
menentukan basisdata dua bukan-awalan, dengan masukan default
sengaja dibiarkan kosong:
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",
},
}
If you attempt to access a database that you haven't defined in your
DATABASES
setting, Django will raise a
django.utils.connection.ConnectionDoesNotExist
exception.
The migrate
management command operates on one database at a
time. By default, it operates on the default
database, but by
providing the --database
option, you can tell it
to synchronize a different database. So, to synchronize all models onto
all databases in the first example above, you would need to call:
$ ./manage.py migrate
$ ./manage.py migrate --database=users
Jika anda tidak ingin setiap aplikasi disinkronkan kedalam basisdata tertentu, anda dapat menentukan database router1 yang menerapkan batasan kebijakan ketersediaan dari model tertentu.
If, as in the second example above, you've left the default
database empty,
you must provide a database name each time you run migrate
. Omitting
the database name would raise an error. For the second example:
$ ./manage.py migrate --database=users
$ ./manage.py migrate --database=customers
Kebanyakan perintah django-admin
lain yang berinteraksi dengan basisdata berjalan dalam cara sama seperti migrate
-- mereka hanya berjalan pada satu basisdata pada satu waktu, menggunakan --database
untuk mengendalikan penggunaan basisdata.
Sebuah pengecualian pada aturan ini adalah perintah makemigrations
. Itu mengecek riwayat perpindahan di basisdata untuk menangkap masalah dengan berkas perpindahan yang ada (yang dapat disebabkan dengan menyunting mereka) sebelum membuat perpindahan baru. Secara awalan, itu memeriksa hanya basisdata default
, tetapi itu merundingkan metode allow_migrate()
dari routers jika apapun terpasang.
Cara termudah menggunakan banyak basisdata adalah menyetel skema perutean basisdata. Skema perutean awalan memastikan bahwa obyek tetap 'sticky' ke basisdata aslinya (yaitu, obyek diambil dari basisdata foo
akan disimpan pada basisdata sama). Skema perute awalan memastikan bahwa jika sebuah absisdata tidak ditentukan, semua permintaan kembali ke basisdata default
.
Anda tidak perlu melakukan apapun untuk mengaktifkan skema perutean awalan -- itu disediakan 'beda dari biasanya' pada setiap proyek Django. Bagaimanapun, jika anda ingin menerapkan lebih menarik perilaku peruntukan basisdata, anda dapat menentukan dan memasang perute basisdata anda sendiri.
Perute basisdata adalah kelas yang menyediakan sampai empat metode:
db_for_read
(model, **hints)¶Sarankan basisdata yang harus digunakan untuk membaca tindakan-tindakan untuk obyek dari jenis model
.
Jika tindakan basisdata dapat menyediakan informasi tambahan apapun yang mungkin membantu dalam memilih basisdata, itu akan menyediakan dalam dictionary hints
. Rincian pada peunjuk sah disediakan below 1.
Mengembalikan None
jika tidak ada saran.
db_for_write
(model, **hints)¶Sarankan basisdata yang harus digunakan untuk menulis dari obyek dari jenis Model.
Jika tindakan basisdata dapat menyediakan informasi tambahan apapun yang mungkin membantu dalam memilih basisdata, itu akan menyediakan dalam dictionary hints
. Rincian pada peunjuk sah disediakan below 1.
Mengembalikan None
jika tidak ada saran.
allow_relation
(obj1, obj2, **hints)¶Mengembalikan True
jika sebuah hubungan diantara obj1
dan obj2
harus diizinkan, False
jika hubungan harus dicegah, atau None
jika perute tidak memiliki pendapat. Ini adalah murni tindakan pengesahan, digunakan oleh foreign key dan tindakan many to many untuk menentukan jika hubungan harus diizinkan diantara dua obyek.
If no router has an opinion (i.e. all routers return None
), only
relations within the same database are allowed.
allow_migrate
(db, app_label, model_name=None, **hints)¶Tentukan jika tindakan perpindahan diizinkan untuk menjalankan pada basisdata dengan nama lain db
. Mengembalikan True
jika tindakan harus berjalan, False
jika itu tidak harus berjalan, atau None
jika perute tidak memiliki pendapat.
Argumen penempatan app_label
adalah label untuk aplikasi sedang dipindahkan.
model_name
disetel oleh kebanyakan tindakan perpindahan pada nilai dari model._meta.model_name
(versi huruf kecil dari model __name__
) dari model sedang dipindahkan. Nilai itu adalah None
untuk tindakan RunPython
dan RunSQL
meskipun mereka menyediakan itu menggunakan petunjuk.
hints
digunakan oleh tindakan tertentu untuk berkomunikasi informasi tambahan ke perute.
Ketika hints
disetel, hints
biasanya mengandung kelas model dibawah kunci 'model'
. Catat bahwa itu mungkin berupa historical model 1, dan dengan demikian tidak mempunyai atribut penyesuaian apapun, metode, atau pengelola. Anda harus hanya bergantung pada _meta
.
Metode ini dapat juga digunakan untuk menentukan ketersediaan dari sebuah model pada basisdata yang diberikan.
makemigrations
selalu membuat perpindahan untuk perubahan model, tetapi jika allow_migrate()
mengembalikan False
, tindakan perpindahan apapun untuk model_name
akan secara diam dilewatkan ketika menjalankan migrate
pada db
. Merubah perilaku dari allow_migrate()
untuk model yang sudah berpindah mungkin menghasilkan rusak dalam foreign key, tabel tambahan, atau tabel hilang. Ketika makemigrations
memeriksa riwayat perpindahan, itu melewati basisdata dimana tidak ada aplikasi diizinkan berpindah.
Perute tidak harus menyediakan semua metode ini -- itu mungkin menghilangkan satu atau lebih dari mereka. Jika satu dari metode ini dihilangkan, Django akan melewati perute itu ketika melakukan pemeriksaan terkait.
Petunjuk diterima oleh perute basisdata dapat digunakan untuk memutuskan basisdata mana harus menerima permintaan yang diberikan.
Saat sekarang, petunjuk satu-satunya akan disediakan adalah instance
, sebuah instance obyek yang terkait ke tindakan baca atau tulis yang berlangsung. Ini mungkin instance yang sedang disimpan, atau itu mungkin berupa sebuah instance yang sedang ditambahkan dalam hubungan many-to-many. Dalam beberapa kasus, tidak ada petunjuk instance akan disediakan sama sekali. Perute memeriksa untuk kehadiran dari sebuah petunjuk instance, dan menentukan jika petunjuk itu harus digunakan untuk merubah perulaku perutean.
Database routers are installed using the DATABASE_ROUTERS
setting. This setting defines a list of class names, each specifying a
router that should be used by the base router
(django.db.router
).
The base router is used by Django's database operations to allocate
database usage. Whenever a query needs to know which database to use,
it calls the base router, providing a model and a hint (if
available). The base router tries each router class in turn until one returns
a database suggestion. If no routers return a suggestion, the base router tries
the current instance._state.db
of the hint instance. If no hint instance
was provided, or instance._state.db
is
None
, the base router will allocate the default
database.
Hanya bertujuan contoh!
Contoh ini dimaksudkan sebagai pertunjukan dari bagaimana infrastruktur perute dapat digunakan untuk mengubah penggunaan basisdata. Itu sengaja mengabaikan beberapa masalah rumit untuk mempertunjukkan bagaimana perute digunakan.
Contoh ini tidak akan bekerja jika apapun dari model dalam myapp
mengandung hubungan pada model diluar dari basisdata other
. Cross-database relationships 1 memperkenalkan masalah kesatuan referensial yang Django tidak dapat saat ini ditangani.
Konfigurasi utama/tiruan (mengacu pada sebagai master/slave oleh beberapa basisdata) digambarkan juga cacat -- itu tidak menyediakan pemecahan apapun untuk menangani tiruan ketinggalan (yaitu permintaan ketidakkonsekuen diperkenalkan karena dari waktu diambil untuk menulis untuk disebarkan ke tiruan). Itu juga tidak mempertimbangkan timbal balik dari transaksi dengan strategi penggunaan basisdata.
Jadi - apa ini artinya dalam praktik? Mari kita pertimbangkan konfigurasi contoh lain. Satu ini akan mempunyai beberapa basisdata: satu untuk aplikasi auth
, dan semua aplikasi lain menggunakan setelah utama/tiruan dengan duatiruan baca. Ini adalah pengaturan menentukan basisdata ini:
DATABASES = {
"default": {},
"auth_db": {
"NAME": "auth_db_name",
"ENGINE": "django.db.backends.mysql",
"USER": "mysql_user",
"PASSWORD": "swordfish",
},
"primary": {
"NAME": "primary_name",
"ENGINE": "django.db.backends.mysql",
"USER": "mysql_user",
"PASSWORD": "spam",
},
"replica1": {
"NAME": "replica1_name",
"ENGINE": "django.db.backends.mysql",
"USER": "mysql_user",
"PASSWORD": "eggs",
},
"replica2": {
"NAME": "replica2_name",
"ENGINE": "django.db.backends.mysql",
"USER": "mysql_user",
"PASSWORD": "bacon",
},
}
Now we'll need to handle routing. First we want a router that knows to
send queries for the auth
and contenttypes
apps to auth_db
(auth
models are linked to ContentType
, so they must be stored in the
same database):
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
Dan kami juga ingin sebuah perute yang mengirim semua aplikasi lain semua ke konfigurasi utama/tiruan, dan secara acak memilih sebuah tiruan untuk dibaca:
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_set = {"primary", "replica1", "replica2"}
if obj1._state.db in db_set and obj2._state.db in db_set:
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
Akhirnya, dalam berkas pengaturan, kami menambahkan berikut (mengganti path.to.
dengan jalur Python sebenarnya pada modul dimana perute ditentukan):
DATABASE_ROUTERS = ["path.to.AuthRouter", "path.to.PrimaryReplicaRouter"]
Urutan dimana perute diolah adalah penting. Perute akan diminta agar mereka didaftarkan dalam pengaturan DATABASE_ROUTERS
. Dalam contoh ini, AuthRouter
diolah sebelum PrimaryReplicaRouter
, dan sebagai hasil, keputusan tentang model-model dalam auth
diolah sebelum keputusan lain apapun dibuat. Jika pengaturan DATABASE_ROUTERS
mendaftarkan dua perute dalam urutan lain, PrimaryReplicaRouter.allow_migrate()
akan diolah dahulu. Tangkap-semua alami dari penerapan PrimaryReplicaRouter akan berarti bahwa semua model-model akan tersedia pada semua basisdata.
With this setup installed, and all databases migrated as per Sinkronisasi basisdata anda, lets run some Django code:
>>> # 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")
Contoh ini menentukan sebuah perute untuk menangani interaksi dengan model-model dari aplikasi auth
, dan perute lain untuk mengangani interaksi dengan semua aplikasi lain. Jika anda membiarkan basisdata default
anda kosong dan tidak ingin menentukan perute basisdata tangkap-semua untuk mengangani semua aplikasi tidak sebaliknya ditentukan, perute anda harus menangani nama-nama dari semua aplikasi dalam INSTALLED_APPS
sebelum anda berpindah. Lihat Perilaku dari aplikasi bantuan untuk informasi tentang apliaksi bantuan yang harus bersama-sama dalam satu basisdata.
Django juga menyediakan sebuah API yang mengizinkan anda merawat kendali lengkap terhadap penggunaan basisdata dalam kode anda. Peruntukan basisdata ditentukan manual terhadap basisdata diperuntukkan oleh sebuah perute.
QuerySet
¶You can select the database for a QuerySet
at any point in the
QuerySet
"chain." Call using()
on the QuerySet
to get another
QuerySet
that uses the specified database.
using()
takes a single argument: the alias of the database on
which you want to run the query. For example:
>>> # This will run on the 'default' database.
>>> Author.objects.all()
>>> # So will this.
>>> Author.objects.using("default")
>>> # This will run on the 'other' database.
>>> Author.objects.using("other")
save()
¶Gunakan kata kunci using
pada Model.save()
untuk menentukan pada basisdata mana data harus disimpan.
For example, to save an object to the legacy_users
database, you'd
use this:
>>> my_object.save(using="legacy_users")
Jika anda tidak menentukan using
, metode save()
kan menyimpan kedalam basisdata awalan ditempatkan oleh perute.
Jika anda menyimpan sebuah instance pada satu basisdata, itu mungkin menggoda untuk menggunakan save(using=...)
sebagai sebuah cara berpindah instance ke basisdata baru. Bagaimanapun, jika anda tidak mengambil langkah-langkah yang sesuai, ini dapat memiliki beberapa konsekuensi tidak diharapkan.
Consider the following example:
>>> p = Person(name="Fred")
>>> p.save(using="first") # (statement 1)
>>> p.save(using="second") # (statement 2)
Dalam pernyataan 1, sebuah obyek Person
baru disimpan ke basisdata first
. Pada saat ini, p
tidak memiliki primary key, jadi Django menerbitkan sebuah pernyataan SQL INSERT
. Ini membuat sebuah primary key, dan Django memberikan primary key itu ke p
.
Ketika penyimpanan muncul dalam pernyataan 2, p
sudah mempunyai nilai primary key, dan Django akan berusaha menggunakan primary key itu pada basisdata baru. Jika nilai primary key tidak digunakan dalam basisdata second
, kemudian akdan tidak mempunyai masalah apapun -- obyek akan disalin ke basisdata baru.
Bagaimanapun, jika primary key dari p
sudah digunakan pada basisdata second
, obyek yang ada dalam basisdata second
akan ditimpan ketika p
disimpan.
You can avoid this in two ways. First, you can clear the primary key
of the instance. If an object has no primary key, Django will treat it
as a new object, avoiding any loss of data on the second
database:
>>> p = Person(name="Fred")
>>> p.save(using="first")
>>> p.pk = None # Clear the primary key.
>>> p.save(using="second") # Write a completely new object.
The second option is to use the force_insert
option to save()
to ensure that Django does an SQL INSERT
:
>>> p = Person(name="Fred")
>>> p.save(using="first")
>>> p.save(using="second", force_insert=True)
Ini akan memastikan bahwa seseorang bernama Fred
akan mempunyai primary key sama pada kedua basisdata. Jika primary key sudah digunakan ketika anda mencoba menyimpan kedalam basisdata kedua
, sebuah kesalahan akan dimunculkan.
By default, a call to delete an existing object will be executed on the same database that was used to retrieve the object in the first place:
>>> u = User.objects.using("legacy_users").get(username="fred")
>>> u.delete() # will delete from the `legacy_users` database
Untuk menentukan basisdata dari model mana akan dihapus, lewatkan sebuah argumen kata kunci using
pada metode Model.delete()
. Argumen ini bekerja seperti argumen kata kunci using
pada save()
.
For example, if you're migrating a user from the legacy_users
database to the new_users
database, you might use these commands:
>>> user_obj.save(using="new_users")
>>> user_obj.delete(using="legacy_users")
Gunakan metode db_manager()
pada pengelola untuk memberikan pengelola mengakses ke basisdata bukan-awalan.
Sebagai contoh, katakan anda mempunyai metode pengelolaan penyesuaian yang menyentuh basisdata -- User.objects.create_user()
. Karena create_user()
adalah metode pengelola, bukan metode QuerySet
, anda tidak dapat melakukan User.objects.using('new_users').create_user()
. (Metode create_user()
hanya tersedia pada User.objects
, pengelola, bukan pada obyek QuerySet
diturunkan dari pengelola.) Pemecahannya adalah menggunakan db_manager()
, seperti ini:
User.objects.db_manager("new_users").create_user(...)
db_manager()
mengembalikan sebuah salinan dari ikatan pengelola pada basisdata anda tentukan.
get_queryset()
dengan basisdata banyak¶Jika anda menimpa get_queryset()
pada pengelola anda, apstikan untuk antara memanggil metode pada induk (menggunakan super()
) atau melakukan penanganan sesuai dari atribut _db
pada pengelola (sebuah string mengandung nama dari basisdata untuk digunakan).
Sebagai contoh, jika anda ingin mengembalikan penyesuaian kelas QuerySet
dari metode get_queryset
, anda dapat melakukan ini:
class MyManager(models.Manager):
def get_queryset(self):
qs = CustomQuerySet(self.model)
if self._db is not None:
qs = qs.using(self._db)
return qs
Admin Django tidak mempunyai dukungan jelas untuk banyak basisdata. Jika anda ingin menyediakan sebuah antarmuka admin untuk sebuah model pada sebuah basisdata daripada selain ditentukan oleh rantai peute anda, anda akan butuh menulis kelas-kelas ModelAdmin
penyesuaian yang akan langsung ke admin untuk menggunakan basisdata khusus untuk isi.
ModelAdmin
objects have the following methods that require customization
for multiple-database support:
class MultiDBModelAdmin(admin.ModelAdmin):
# A handy constant for the name of the alternate database.
using = "other"
def save_model(self, request, obj, form, change):
# Tell Django to save objects to the 'other' database.
obj.save(using=self.using)
def delete_model(self, request, obj):
# Tell Django to delete objects from the 'other' database
obj.delete(using=self.using)
def get_queryset(self, request):
# Tell Django to look for objects on the 'other' database.
return super().get_queryset(request).using(self.using)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
# Tell Django to populate ForeignKey widgets using a query
# on the 'other' database.
return super().formfield_for_foreignkey(
db_field, request, using=self.using, **kwargs
)
def formfield_for_manytomany(self, db_field, request, **kwargs):
# Tell Django to populate ManyToMany widgets using a query
# on the 'other' database.
return super().formfield_for_manytomany(
db_field, request, using=self.using, **kwargs
)
Penerapan disediakan disini menerapkan strategi banyak-basisdata dimana semua obyek dari jenis yang diberikan disimpan pada basisdata khusus (sebagai contoh, semua obyek User
dalam basisdata lain
). Jika penggunaan anda dari banyak basisdata lebih rumit, ModelAdmin
anda akan butuh mencerminkan strategi itu.
Obyek InlineModelAdmin
dapat ditangani di gaya yang mirip. Mereka membutuhkan tiga metode penyesuaian:
class MultiDBTabularInline(admin.TabularInline):
using = "other"
def get_queryset(self, request):
# Tell Django to look for inline objects on the 'other' database.
return super().get_queryset(request).using(self.using)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
# Tell Django to populate ForeignKey widgets using a query
# on the 'other' database.
return super().formfield_for_foreignkey(
db_field, request, using=self.using, **kwargs
)
def formfield_for_manytomany(self, db_field, request, **kwargs):
# Tell Django to populate ManyToMany widgets using a query
# on the 'other' database.
return super().formfield_for_manytomany(
db_field, request, using=self.using, **kwargs
)
Sekali anda telah menulis pengertian admin model anda, mereka dapat didaftarkan dengan instance Admin
apapun:
from django.contrib import admin
# Specialize the multi-db admin objects for use with specific models.
class BookInline(MultiDBTabularInline):
model = Book
class PublisherAdmin(MultiDBModelAdmin):
inlines = [BookInline]
admin.site.register(Author, MultiDBModelAdmin)
admin.site.register(Publisher, PublisherAdmin)
othersite = admin.AdminSite("othersite")
othersite.register(Publisher, MultiDBModelAdmin)
Contoh ini menyetel dua situs admin. Pada situs pertama, obyek-obyek Author
dan Publisher
dibuka; obyek-obyek Publisher
mempunyai sebuah dibarisan datar menunjukkan buku-buku diterbitkan oleh penerbit. Situs kedua membuka hanya penerbit, tanpa barisan.
Jika anda menggunakan lebih dari satu basisdata anda dapat menggunakan django.db.connections
untuk mengambil hubungan (dan kursor) untuk basisdata tertentu. django.db.connections
adalah objek seperti-kamus yang mengizinkan anda mengambil hubungan tertentu menggunakan nama lainnya:
from django.db import connections
with connections["my_db_alias"].cursor() as cursor:
...
Django saat ini tidak menyediakan dukungan apapun untuk foreign key atau hubungan many-to-many menjangkau banyak basisdata. Jika anda telah menggunakan sebuah perute pada model sebagian ke basisdata berbeda, foreign key apapun dan hubungan many-to-many ditentukan oleh modek-model tersebut harus secara internal pada basisdata tunggal.
Ini karena dari kesatuan referensial. Untuk merawat hubungan diantara dua obyek, Django butuh mengetahui bahwa primary key dari obyek terkait adalah sah. Jika primary key disimpan pada basisdata terpisah, itu tidak mungkin dengan mudah menilai keabsahan primary key.
Jika anda sedang menggunakan Postgres, Oracle, atau MySQL dengan InnoDB, ini dipaksa pada tingkat kesatuan basisdata -- batasan kunci tingkatan basisdata mencegah dari pembuatan dari hubungan yang tidak dapat disahkan.
Bagaimanapun, jika anda sedang menggunakan SQLite atay MySQL dengan tabel MyISAM, tidak ada pemaksaan kesatuan referensial; sebagai hasil, anda mungkin dapat me 'niru' foreign key basisdata. bagaimanapun, konfigurasi ini tidak secara resmi didukung oleh Django.
Beberapa aplikasi bantuan termasuk model-model, dan beberapa aplikasi bergantung pada lainnya. Sejak hubungan silang-basisdata tidak dimungkinkan, ini membuat beberapa pembatasan pada bagaimana anda dapat memisahkan model-model ini terhadap basisdata:
contenttypes.ContentType
, sessions.Session
dan sites.Site
dapat disimpan dalam basisdata apapun, diberikan perute yang cocok.auth
— User
, Group
dan Permission
— dikaitkan bersama-sama dan dikaitkan pada ContentType
, sehingga mereka harus disimpan dalam basisdata sama sebagai ContentType
.admin
bergantung pada auth
, jadi modelnya harus di basisdata sama seperti auth
.flatpages
dan redirects
bergantung pada sites
,jadi model-model mereka harus di basisdata yang sama seperti sites
.Sebagai tambahan, beberapa obyek otomatis dibuat hanya setelah migrate
membuat tabel untuk menahan mereka dalam basisdata:
Site
awal,ContentType
untuk setiap model (termasuk itu tidak disimpan di basisdata itu),Permission
s for each model (including those not stored in that
database).Untuk pengaturan umum dengan banyak basisdata, itu tidak berguna memiliki obyek-obyek ini dalam lebih dari satu basisdata. Pengaturan umum menyertakan utama/tiruan dan menghubungkan ke basisdata luar. Karena itu, itu dianjurkan untuk menulis database router1 yang mengizinkan mensinkronkan ketiga model ini pada hanya satu basisdata. Gunakan pendekatan sama untuk aplikasi bantuan dan pihak-ketiga yang tidak butuh tabel mereka dalam banyak basisdata.
Peringatan
Jika anda sedang mensinkronkan jenis-jenis isi ke lebih dari satu basisdata, waspada bahwa primary key mereka mungkin tidak cocok terhadap basisdata. Ini mungkin menghasilkan kerusakan data atau kehilangan data.
Des 04, 2023