假设我们有一个电商平台,其中包含用户、订单、商品三个模型,我们希望将这三个模型分别存储在不同的数据库中。

首先,在 settings.py 中配置数据库连接:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'default_db',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
    'user_db': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'user_db',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
    'order_db': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'order_db',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
    'product_db': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'product_db',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
}

接着,在 models.py 中定义模型,并指定数据库:

class User(models.Model):
    name = models.CharField(max_length=20)
    email = models.EmailField()

    class Meta:
        app_label = 'user'
        db_table = 'user'
        managed = False
        using = 'user_db'
class Order(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    total_price = models.FloatField()

    class Meta:
        app_label = 'order'
        db_table = 'order'
        managed = False
        using = 'order_db'
class Product(models.Model):
    name = models.CharField(max_length=50)
    price = models.FloatField()

    class Meta:
        app_label = 'product'
        db_table = 'product'
        managed = False
        using = 'product_db'

其中,Meta 中的 app_label 和 db_table 分别指定应用名和表名,using 指定使用的数据库。

最后,在 settings.py 中配置路由:

DATABASE_ROUTERS = [
    'user.db_routers.UserRouter',
    'order.db_routers.OrderRouter',
    'product.db_routers.ProductRouter',
]

并在每个应用中创建 db_routers.py 文件:

class UserRouter:
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'user':
            return 'user_db'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'user':
            return 'user_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == 'user' or obj2._meta.app_label == 'user':
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label == 'user':
            return db == 'user_db'
        return None
class OrderRouter:
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'order':
            return 'order_db'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'order':
            return 'order_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == 'order' or obj2._meta.app_label == 'order':
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label == 'order':
            return db == 'order_db'
        return None
class ProductRouter:
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'product':
            return 'product_db'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'product':
            return 'product_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == 'product' or obj2._meta.app_label == 'product':
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label == 'product':
            return db == 'product_db'
        return None

以上是一个简单的 Django 分库使用范例。当然,实际应用中可能还有更多的复杂情况需要处理,比如数据同步、数据迁移等。

Django 分库实战:电商平台用户、订单、商品模型分离存储

原文地址: https://www.cveoy.top/t/topic/nx6l 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录