Django 动态分表

本文记录了在Django中根据应用名实现动态分表的思路和具体实现过程。通过动态设定Meta类属性,创建新类以操作对应应用名的数据库表。然而,由于动态创建的Model不享受自动建表的待遇,需要手动创建数据表或在首次操作时自动创建。

前言

正式开始上班了。工作中遇到个问题,就是在Django中要根据应用名进行动态分表。实现时遇到点问题,在这里记录下整体的思路和实现。

具体任务

利用DjangoORM机制根据应用名实现动态分表。简单来说就是保持Model结构不变的情况下,可以在服务器运行时,动态在应用名对应的表内进行数据库操作。每个应用独立出一张表。所有表的结果相同。

思路

Django中的每个Model对应数据库中的一张表。每个Model也就是一个继承自django.models.ModelPython类。每个类正常是包含三个部分:

  1. 类属性。每个类属性对应表中的一个字段。
  2. Meta嵌套类。Meta嵌套类中也包含了一些类属性。常见的有 db_table 和 app_label。db_table定义了这个Python类对应的表名。app_label则定义了这个Python类对应的应用名。
  3. 类方法/实例方法。这些方法不是必须有的。可以根据需要进行编写。

如上所言,类属性定义了表的结构。而Meta嵌套类则决定了表名
因此如果能够在代码中根据应用名动态切换Meta嵌套类的类属性,也就实现了根据应用名动态分表的功能。
实际实现时,就是定义一个类方法,根据应用名,设定Meta嵌套类具体类属性,然后使用type基于原有的Python类的类属性和新的Meta嵌套类创建一个新类。使用新类基于ORM机制操作数据表。

具体实现

from django.db import models


class AppLog(models.Model):
    full_name = models.CharField(max_length=2048)
    creator = models.CharField(max_length=30)
    create_time = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = "file_log"
        app_label = 'app'

    @classmethod
    def get_app_log_model(cls, app_name):
        class Meta:
            db_table = '{}_{}'.format(app_name, cls._meta.db_table)
            app_label = cls._meta.app_label

        attrs = {
            'Meta': Meta,
            '__module__': cls.__module__,
        }

        return type(cls._meta.db_table, (AppLog, ), attrs)

          

写完后,记得makemigrationsmigrate同步下数据库。
走到这,是不是以为大功告成了。
来,测试下。
测试失败1测试失败2
执行报错了。
但是从报错信息来看,ORM操作数据表时已经定向到test_file_log这张表。只不过这张表不存在
看到这里,就会产生一点疑问,明明已经同步过数据库了,为什么数据表会不存在呢,不是说好的自动创建。
这里其实就涉及到另外一个问题了。Djangomakemigrationsmigrate机制针对的都是明明白白写清楚的,继承自django.models.Model类的Python类。而本文中动态获取到的model由于是动态创建的,所以并不会享受到自动创建数据表的待遇。老老实实地手动创建数据表吧。

总结

这里总结下最终的实现方法。

  1. 修改model的代码。
  2. 手动创建数据表。你要是不想手动创建,也可以写个方法在第一次进行分表查询或插入时,调用方法进行自动创建对应的数据表。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值