django分表存儲的model設計
import json
from django.db import models
from django.http import HttpResponse
class Object:
def init(self, **kwargs):
self.dict.update(kwargs)
def _model_new(cls, args, **kwargs):
return cls(args, **kwargs)
class ShardModel(object):
"""
ShardModel support table horizontal partition.
"""
_shard_db_models = {}
def __new__(cls, *args, **kwargs):
shard_key = kwargs.pop('shard_key', 0) # % cls.Config.table_num
model_name = cls.__name__
model_name += '_%s' % shard_key
model_class = cls._shard_db_models.get(model_name)
if model_class is not None:
return model_class
# Deep copy attrs
attrs = dict()
attrs.update(cls.__dict__)
if 'objects' in attrs:
attrs['objects'] = attrs['objects'].__class__()
# Set table name with shard_key
meta = Object(**cls.Meta.__dict__)
meta.db_table = meta.db_table % shard_key
attrs['Meta'] = meta
attrs['new'] = classmethod(_model_new)
# Create model class dynamically
model_class = type(model_name, tuple([models.Model] + list(cls.__bases__[1:])), attrs)
cls._shard_db_models[model_name] = model_class
return model_class
class Stockbasic(models.Model):
""" 股票基础信息数据,包括股票代码、名称、上市日期、退市日期等 """
ts_code = models.CharField(verbose_name="TS代码", max_length=20, unique=True)
symbol = models.CharField(verbose_name="股票代码", max_length=20)
name = models.CharField(verbose_name="股票名称", max_length=30)
area = models.CharField(verbose_name="地域", max_length=20)
industry = models.CharField(verbose_name="所属行业", max_length=20)
fullname = models.CharField(verbose_name="股票全称", max_length=50)
enname = models.CharField(verbose_name="英文全称", max_length=50)
cnspell = models.CharField(verbose_name="拼音缩写", max_length=10)
market = models.CharField(verbose_name="市场类型", max_length=10)
exchange = models.CharField(verbose_name="交易所代码", max_length=10)
curr_type = models.CharField(verbose_name="交易货币", max_length=10)
list_choice = (
("L", "上市"),
("D", "退市"),
("P", "暂停上市"),
)
list_status = models.SmallIntegerField(verbose_name="上市状态", choices=list_choice, default="L")
list_date = models.DateField(verbose_name="上市日期")
delist_date = models.DateField(verbose_name="退市日期")
hs_choice = (
("N", "否"),
("H", "沪股通"),
("S", "深股通"),
)
is_hs = models.SmallIntegerField(verbose_name="是否沪深港通标的", choices=hs_choice, default="N")
def __str__(self):
return self.ts_code
class Share(ShardModel):
ts_code = models.ForeignKey(verbose_name="股票代码", to="Stockbasic", to_field="ts_code", on_delete=models.CASCADE)
trade_date = models.DateField(verbose_name="交易日期")
open = models.DecimalField(verbose_name="开盘价", max_digits=18, decimal_places=2)
high = models.DecimalField(verbose_name="最高价", max_digits=18, decimal_places=2)
low = models.DecimalField(verbose_name="最低价", max_digits=18, decimal_places=2)
close = models.DecimalField(verbose_name="收盘价", max_digits=18, decimal_places=2)
pre_close = models.DecimalField(verbose_name="昨收价(前复权)", max_digits=18, decimal_places=2)
change1 = models.DecimalField(verbose_name="涨跌额", max_digits=18, decimal_places=2)
pct_chg = models.DecimalField(verbose_name="涨跌幅", max_digits=18, decimal_places=2)
vol = models.DecimalField(verbose_name="成交量(手)", max_digits=18, decimal_places=2)
amount = models.DecimalField(verbose_name="成交额(千元)", max_digits=18, decimal_places=2)
class Meta:
app_label = 'default'
db_table = 'share%s'
通过继承ShardModel,Share类就具备的自动分表的功能。 在views中可通过如下方法获取table: share601018......等:
def get_share_info(request):
ts_code = int(request.GET.get('ts_code'))
share = models.User(shard_key=ts_code).objects.get(share_id=ts_code)
return HttpResponse(json.dumps(model_to_dict(share)))