Django中利用type動態操作數據庫表


場景分析:

后台MySql數據庫保存了一大批按股票代碼命名的數據表,每張表保存的是每只股票的日線數據。

stock_000002

stock_600030

stock_600020

...一共3000多個表。

Django中如果要按股票代碼展示每張表的數據,利用常規ORM模型變得非常困難,因為有3000多個表,就需要建3000多個模型。

 

解決辦法:

1. 根據表名、字段等動態創建ORM表模型

def create_model(name, fields=None, app_label='', module='', options=None, admin=None):
    class Meta:
        pass
    if app_label:
        setattr(Meta, 'app_label', app_label)
    if options is not None:
        for key, value in options.items():
            setattr(Meta, key, value)
    attrs = {'__module__': module, 'Meta': Meta}
    if fields:
        attrs.update(fields)
    # 繼承models.Model
    return type(name, (models.Model,), attrs)

 

2. 調用create_model, 返回的custom_model就是表對應的ORM模型

def new_stock(tab_name):
    """
    動態創建數據模型
    :param tab_name: 表名
    :return: 返回模型類
    """
    fields = {
        'ts_code': models.CharField(max_length=20),
        'trade_date': models.CharField(max_length=20, unique=True),
        'open': models.FloatField(null=False, default=0.0),
        'high': models.FloatField(null=False, default=0.0),
        'low': models.FloatField(null=False, default=0.0),
        'close': models.FloatField(null=False, default=0.0),
        'pre_close': models.FloatField(null=False, default=0.0),
        'change': models.FloatField(null=False, default=0.0),
        'pct_chg': models.FloatField(null=False, default=0.0),
        'vol': models.FloatField(null=False, default=0.0),
        'amount': models.FloatField(null=False, default=0.0)
    }
    options = {'ordering': ['trade_date'], 'db_table': tab_name, }
    custom_model = create_model(tab_name, fields, options=options, app_label='stock', module='stock.models')
    return custom_model

 

3. http請求按日期降序排列的股票日線數據。

def stock_detail(request, pk):
    tab_name = 'stock_' + pk
    stock_mod = new_stock(tab_name)

    # 查詢
    if request.method == 'GET':
        limit = request.GET.get('limit')
        offset = request.GET.get('offset')
        # 查詢總記錄條數
        total = stock_mod.objects.count()

        # 結果按日期降序排列
        datalist = stock_mod.objects.all().order_by('-trade_date')[int(offset): int(offset)+int(limit)]
        json_list = []

        import json
        # 返回json字符串
        for data in datalist:
            json_dict = model_to_dict(data)
            json_list.append(json_dict)

        result = dict()
        rows = list()
        result['total'] = total
        result['rows'] = json_list

        logger.info('獲取股票列表')
        return JsonResponse(result, safe=False)

HTTP請求:GET /stock/000002/?offset=0&limit=10

000002與"stock_"組合成表名"stock_000002"

offset為數據的起始位置

limit為返回數據的條數

按表查詢得到的datalist數據組織成json格式返回瀏覽器。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM