mysql提供了区分表的功能, 用于水平分表, 可以减少sql查询时间。
但是django官方并没有配置控制mysql区分表的功能。 网上很多都是从代码层面,使用路由进行分发到不同表,从而进行分表的功能。找了半天终于找到一个开源库,但是作者并没有太完善此功能。还是有许多限制的。如果有老哥找到好的开源库或者有更好的解决方案又或者博客写得有误,欢迎指正讨论。
https://github.com/maxtepkeev/architect
下面就介绍一下用法。architect支持两种数据库, PostgreSQL和mysql, 我只踩过mysql的坑, 就默认在mysql上操作。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
1、所支持的类型。
import architect
@architect.install('partition', type='range', subtype='date', constraint='month', column='columnname')
class Model(object):
pass
(1)type:这里就支持range类型。有点蛋疼。
(2)subtype:就只有data选项。
(3) constraint: 支持4种方式, 也就是新数据如果是不在旧分区里面的, 就会创建一个新分区。
- day: 每天都会创建一个新分区
- week: 每周将创建一个新分区
- month: 每个月都会创建一个新分区
- year: 每年将创建一个新分区
(4)column: 就是你需要控制的字段名称。
2、如何使用:
# models.py
@architect.install('partition', type='range', subtype='date', constraint='day', column='start_time')
class PracticeAttempt(models.Model):
id = models.AutoField(primary_key=True)
user_id = models.IntegerField()
question_id = models.IntegerField()
time_taken = models.IntegerField(default=0)
num_attempts = models.IntegerField(default=1)
start_time = models.DateTimeField()
bookmark = models.IntegerField(default=0)
# 执行命令
python manage.py makemigrations
python manage.py migrate
export DJANGO_SETTINGS_MODULE=django_pro.settings
architect partition --module app01.models
# apps.py 自动创建新的分区
from architect.commands import partition
from django.apps import AppConfig
from django.db import ProgrammingError
from django.db.models.signals import post_migrate
def create_partitions(sender, **kwargs):
"""
After running migrations, go through each of the models
in the app and ensure the partitions have been setup
"""
paths = {model.__module__ for model in sender.get_models()}
for path in paths:
try:
partition.run(dict(module=path))
except ProgrammingError:
# Possibly because models were just un-migrated or
# fields have been changed that effect Architect
print("Unable to apply partitions for module '{}'".format(path))
else:
print("Applied partitions for module '{}'".format(path))
class App01Config(AppConfig):
name = 'app01'
def ready(self):
super(App01Config, self).ready()
# Hook up Architect to the post migrations signal
post_migrate.connect(create_partitions, sender=self)
# views.py
from .models import PracticeAttempt
from django.utils import timezone
class Practice(APIView):
def get(self, request):
user_id = 1
question_id = 1
start_time = timezone.now()
PracticeAttempt.objects.create(user_id=user_id, question_id=question_id, start_time=start_time)
return APIResponse()
1、BUG
(1)django.db.utils.InterfaceError: (0, '') in MySQL。
django连接mysql会自动断开,这个时候我们需要重新建立连接,否则访问接口就会出现异常报错了, 执行之前需要判断是否断开连接。 如果使用ORM的话, 就需要去修改源码:
在pymsql中cursons.py中
加上
conn.ping(reconnect=True)