热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何将python3的flask+mysql的多重循环数据显示在一张表中?

背景:新手上路,第一次用基于python3的flask做web,然后数据库用的mysql目的:有一张人工维护的excel表,横轴是每个月的1-31天,纵轴是参与者名字及月初定的目标,然后每个人
背景:新手上路,第一次用基于python3的flask做web,然后数据库用的mysql

目的:有一张人工维护的excel表,横轴是每个月的1-31天,纵轴是参与者名字及月初定的目标,然后每个人的数据,按天记录在后面,每个人的记录在每个月内一般只有5-15条,有少的可能一个月内只有1-5条



如下:

姓名      |      目标     |    1     |    2    |    3      |     4  |  ......    | 31 |

张三           1000          300                            100              200         

李四            2000                     100                200              100

王五           3000          100       100      100                          200



将以上表的数据转换为mysql的数据库

姓名和目标在一个goals表

姓名和reocrd数据在records表



这些都ok了,flask实现了goals的添加/修改/显示,records的添加/修改/显示

现在对以上表格的web化,不会弄了



flask部分:
先取所有用户的goals dict:      select name,goal from goals  省略转换为dict的代码
然后for循环分别取每个用户的所有records
records dict:    select name,record,day  from records where name =%s  省略转换为dict的代码
这里的问题就是查询了N次了,速度非常慢,如果有几百个用户,那就查询几百次了,先暂时拿一二十个用户实验,就没管这里了,求指点如何优化这里或整体?



jinjia2的web模板中

先固定表头:姓名,目标,接着用for循环生成一个月的31个栏目

内容部分就懵逼了,前面的姓名和目标倒是很简单,后面的records和日期一一对应需要如何实现?

前2项内容:

for   goal in goals:

      goal.name

      goal.goal

后面record和日历的每一天怎么匹配?这里就错了,明显二个for循环不匹配了

for d in range(1,32)

     for    record   in records

            if  record.day == d      // record.day匹配31天中的日期

                            record.record

             else

                        x           //其他需要显示空白

             endif

     endfor

endfor

求指点,应该如何让每个人的record和天数匹配后在31天中正确的时间点显示。

谢谢


11 个解决方案

#1


我的想法, 是生成一个 人数*33 的列表, 第一列是姓名,第二列是目标, 后面31 列对应日期
把所有人和姓名读入,填入第1,2列。 
所有工作数据读入, 按姓名,日期,填入 对应的位置。

最后再显示输出,  输出用  flask 的模板方法。 就是建立个HTML , 数据用{} 标出, 就是类似于 {% for jsfile_name in script_list %}。

#2


感谢回复!
就是如何生成这个人数*33的列表是关键了
1. 人数列循环好处理
2. 以人数列的人名为参数(第一次for循环),循环X遍来读取数据库,遍历出每个人的所有record,有多少人,就得读取执行多少次sql查询
3. 最后将按人名读出来的record(第二次for循环),再按天来循环一次排列(第三次for循环),如果record中的天数和日历数值匹配了,就显示record值,如果不匹配,就显示空白

就是我上面的思路,但是做出来不行,应该是哪里不对,就是第三步,没办法二个循环插入一个横轴中,水平太菜,完全没写过啥代码的菜鸟

#3


2. 以人数列的人名为参数(第一次for循环),循环X遍来读取数据库,遍历出每个人的所有record,有多少人,就得读取执行多少次sql查询
3. 最后将按人名读出来的record(第二次for循环),再按天来循环一次排列(第三次for循环),如果record中的天数和日历数值匹配了,就显示record值,如果不匹配,就显示空白

这个做一次查询即可。
data_array 是大列表   list 是读出来的工作数据 
for l in list:
     //l[0]  是姓名
     for i in range(len(data_array)):
          if data_array[i][0] == l[0]
                 把l 按天数  填入  data_array[i] 


大概思路。慢慢研究

#4


我本身对Django比较熟悉一些,对flask只是如果你用flask难道不用flask-sqlalchemy么?

当然了祼SQL也是可以的。关键是要设计好关系。
按照你的需求你建的库结构应该是这样的

表一、user
id,name,sex, dept, other-info....

表二、record
id, user_id, month, goal, day1, day2, day3, ...., day31

表二的user_id外键关联到表一.id,方式为级联删除。也就是说删除一个表一的user那么他在表二中的所有工作记录也都级联删除。
查询每个月的数据时就会非常方便了,也用不着什么嵌套循环了。

SELECT U.id, U.name, R.goal, R.day1, R.day2...,R.day31 
FROM user AS U LEFT JOIN record AS R ON U.id=R.user_id
WHERE mOnth='2018-03';


#5


引用 3 楼 seakingx 的回复:
2. 以人数列的人名为参数(第一次for循环),循环X遍来读取数据库,遍历出每个人的所有record,有多少人,就得读取执行多少次sql查询
3. 最后将按人名读出来的record(第二次for循环),再按天来循环一次排列(第三次for循环),如果record中的天数和日历数值匹配了,就显示record值,如果不匹配,就显示空白

这个做一次查询即可。
data_array 是大列表   list 是读出来的工作数据 
for l in list:
     //l[0]  是姓名
     for i in range(len(data_array)):
          if data_array[i][0] == l[0]
                 把l 按天数  填入  data_array[i] 


大概思路。慢慢研究


谢谢回复!我研究一下如何搞成一次查询取结果。

另外,您这里的for循环,少了一个生成31天日历的循环,难度横轴要自己手工把31天都列出来?加上这个以后,就是3个for循环了,然后就不能在一个table里显示了。

#6


引用 4 楼 xpresslink 的回复:
我本身对Django比较熟悉一些,对flask只是如果你用flask难道不用flask-sqlalchemy么?

当然了祼SQL也是可以的。关键是要设计好关系。
按照你的需求你建的库结构应该是这样的

表一、user
id,name,sex, dept, other-info....

表二、record
id, user_id, month, goal, day1, day2, day3, ...., day31

表二的user_id外键关联到表一.id,方式为级联删除。也就是说删除一个表一的user那么他在表二中的所有工作记录也都级联删除。
查询每个月的数据时就会非常方便了,也用不着什么嵌套循环了。

SELECT U.id, U.name, R.goal, R.day1, R.day2...,R.day31 
FROM user AS U LEFT JOIN record AS R ON U.id=R.user_id
WHERE mOnth='2018-03';

抱歉,纯菜鸟,不懂flask-sqlalchemy,就是按flask的官方文档写的,把sqllite改成mysql了,我搜一下,哈哈!
试试按您这个方法改一下,这个多次查询也许能解决掉,但主要问题是在table中显示数据就不会头绪了……

#7


另外,每个人的数据不是31天每天都有,只有几天会有,例如一个人只会有5条,打个比方,3号,8号,10号,15号,20号,就没有了,每个人也是没规律的,不能在database查询时直接把31天的record都按顺序查询出来吧?
一个人还好点,要是人多就不行了吧

#8


你的EXCEL里的结构是每个人都有31个值 ,  数据库也可以这样设计, 我觉得鳄鱼大神的思路不错, 和EXCEL一一对应。

这样每个人的数据就是1行。 那些没有数据的, 可以为0。  你在生成表格时, 可以让   内为空。
3次循环生成 大列表

2次循环生成输出的表格。

#9


数据库里按天加31个值,方法倒是笨了点,不过这个好像是可以解决显示的问题……
现在我就是只加了一个值,对应的是date选项,然后就得去判断这个date是否和table里的天数想匹配

#10


敢问大神们,还有更好的办法吗?
不大想在数据库里面挨个把31天都加上,希望能有个更完美的解决办法

#11


Flask的代码:


    cursor.execute('SELECT name, distances from goals where DATE_FORMAT(date, "%Y%m") = DATE_FORMAT(CURDATE(), "%Y%m") ')
    goals = [dict(name=row[0], distances=row[1]) for row in cursor.fetchall()]
    
    monthly = []
    for goal in goals:
        # get month records with name
        sql = 'SELECT name,DATE_FORMAT(date, "%e"),distance FROM records WHERE DATE_FORMAT(date, "%Y%m") = DATE_FORMAT(CURDATE(), "%Y%m") and name = %s order by date'
        cursor.execute(sql, (goal["name"], ))
        records = [dict(name=row[0], day=row[1], distance=row[3]) for row in cursor.fetchall()]
        monthly.append(dict(goal, counts=len(records), records=records))
    #close db
    close_db()
    return render_template('index.html', mOnthly=monthly)




实际的jinjia2 index.html模板:


  
    
    
      ID
      Name
      Distances
      Counts
      
      {% for m in range(1,32) %}
         {{ m }}-Mar
      {% endfor %}

    
    
    
  
  {% for month in monthly %}
  
      
      {{ loop.index }}
      {{ month.name }}
      {{ month.distances }}KM
      {{ month.counts }}

      {% for m in range(1,32) %} 
          {% for record in month.records %}
            {% if record.day == m %}
              {{ record.distance }}
            {% endif %}
            {{ record.day }}
          {% endfor %}
      {% endfor %}

    
  {% else %}
    No record
  {% endfor %}

    
  


推荐阅读
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • importpymysql#一、直接连接mysql数据库'''coonpymysql.connect(host'192.168.*.*',u ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • C# 中 SQLite 报错:在 "\\s\\" 附近出现语法错误,如何解决? ... [详细]
  • MySQL的查询执行流程涉及多个关键组件,包括连接器、查询缓存、分析器和优化器。在服务层,连接器负责建立与客户端的连接,查询缓存用于存储和检索常用查询结果,以提高性能。分析器则解析SQL语句,生成语法树,而优化器负责选择最优的查询执行计划。这一流程确保了MySQL能够高效地处理各种复杂的查询请求。 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 为了确保数据库的高效运行,本文介绍了一种方法,通过编写定时任务脚本来自动清理 `order` 表中状态为 0 或为空的无效订单记录。该脚本使用 PHP 编写,并设置时区为中国标准时间,每 10 分钟执行一次,以保持数据库的整洁和性能优化。此外,还详细介绍了如何配置定时任务以及脚本的具体实现步骤。 ... [详细]
  • 在使用 Cacti 进行监控时,发现已运行的转码机未产生流量,导致 Cacti 监控界面显示该转码机处于宕机状态。进一步检查 Cacti 日志,发现数据库中存在 SQL 查询失败的问题,错误代码为 145。此问题可能是由于数据库表损坏或索引失效所致,建议对相关表进行修复操作以恢复监控功能。 ... [详细]
  • 如何高效地安装并配置 PostgreSQL 数据库系统?本文将详细介绍从下载到安装、配置环境变量、初始化数据库、以及优化性能的全过程,帮助读者快速掌握 PostgreSQL 的核心操作与最佳实践。文章还涵盖了常见问题的解决方案,确保用户在部署过程中能够顺利解决遇到的各种挑战。 ... [详细]
  • SQL 连接详解与应用
    本文详细介绍了 SQL 连接的概念、分类及实际应用,包括内连接、外连接、自连接等,并提供了丰富的示例代码。 ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 本文总结了在SQL Server数据库中编写和优化存储过程的经验和技巧,旨在帮助数据库开发人员提升存储过程的性能和可维护性。 ... [详细]
  • php更新数据库字段的函数是,php更新数据库字段的函数是 ... [详细]
  • 通过使用Sqoop导入工具,可以精确控制并高效地将表数据的特定子集导入到HDFS中。具体而言,可以通过在导入命令中添加WHERE子句来指定所需的数据范围,从而在数据库服务器上执行相应的SQL查询,并将查询结果高效地存储到HDFS中。这种方法不仅提高了数据导入的灵活性,还确保了数据的准确性和完整性。 ... [详细]
  • 在分析和解决 Keepalived VIP 漂移故障的过程中,我们发现主备节点配置如下:主节点 IP 为 172.16.30.31,备份节点 IP 为 172.16.30.32,虚拟 IP 为 172.16.30.10。故障表现为监控系统显示 Keepalived 主节点状态异常,导致 VIP 漂移到备份节点。通过详细检查配置文件和日志,我们发现主节点上的 Keepalived 进程未能正常运行,最终通过优化配置和重启服务解决了该问题。此外,我们还增加了健康检查机制,以提高系统的稳定性和可靠性。 ... [详细]
author-avatar
toto333
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有