django分表存儲的model

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)))
posted @ 2023-07-07 08:59  冀未然  阅读(63)  评论(0)    收藏  举报