zoukankan      html  css  js  c++  java
  • 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格式返回浏览器。

  • 相关阅读:
    Redis详解----- 缓存穿透、缓存击穿、缓存雪崩
    mysql存储时间
    MAT入门到精通
    meven依赖思考记录
    线程池原理
    vscode + wsl2
    java架构师学习路线-高级
    java架构师学习路线-初级
    (二)垃圾回收
    (一)内存区域
  • 原文地址:https://www.cnblogs.com/bryant24/p/11445688.html
Copyright © 2011-2022 走看看