忘记密码   免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 1453 | 回复: 0

python读mysql数据库二张表按日历生成表格 [复制链接]

论坛徽章:
0
发表于 2018-03-13 18:14 |显示全部楼层
背景:新手上路,第一次用基于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化,不会弄了


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


flask的代码部分:


  1.     cursor.execute('SELECT name, distances from goals where DATE_FORMAT(date, "%Y%m") = DATE_FORMAT(CURDATE(), "%Y%m") ')
  2.     goals = [dict(name=row[0], distances=row[1]) for row in cursor.fetchall()]
  3.    
  4.     monthly = []
  5.     for goal in goals:
  6.         # get month records with name
  7.         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'
  8.         cursor.execute(sql, (goal["name"], ))
  9.         records = [dict(name=row[0], day=row[1], distance=row[3]) for row in cursor.fetchall()]
  10.         monthly.append(dict(goal, counts=len(records), records=records))
  11.     #close db
  12.     close_db()
  13.     return render_template('index.html', monthly=monthly)


复制代码


实际的jinjia2 index.html模板:





  1.   <table class="hover">
  2.     <thead>
  3.     <tr>
  4.       <th width="150">ID</th>
  5.       <th width="150">Name</th>
  6.       <th width="150">Distances</th>
  7.       <th width="150">Counts</th>
  8.       
  9.       {% for m in range(1,32) %}
  10.          <th>{{ m }}-Mar</th>
  11.       {% endfor %}

  12.     </tr>
  13.     </thead>
  14.     <tbody>
  15.   
  16.   {% for month in monthly %}
  17.   
  18.       <tr>
  19.       <td>{{ loop.index }}</td>
  20.       <td>{{ month.name }}</td>
  21.       <td>{{ month.distances }}KM</td>
  22.       <td>{{ month.counts }}</td>

  23.       {% for m in range(1,32) %}
  24.           {% for record in month.records %}
  25.             {% if record.day == m %}
  26.               <td>{{ record.distance }}</td>
  27.             {% endif %}
  28.             <td>{{ record.day }}</td>
  29.           {% endfor %}
  30.       {% endfor %}

  31.     </tr>
  32.   {% else %}
  33.     <tr><td>No record</td></tr>
  34.   {% endfor %}

  35.     </tbody>
  36.   </table>

复制代码


先不考虑数据库多次查询的问题,如何将二张表里的数据,以日期顺序显示在web上,主要是三次for循环出问题了
另外,还有个特别笨的办法就是在数据库records里面按日期添加31个字段,然后写入的时候按天数写入,这个就太XX了,还是希望有个更先进的解决办法。

每个人的数据不是整月31天每天都有,只会有几天才会有,例如一个人只会有5条,打个比方,3号,8号,10号,15号,20号,就没有了,是没规律的

另外,也尝试直接把数据先读到python里面,生成符合这个table的数据格式,再用jinjia2的html模板生成,也一样面临这3个for循环嵌套的问题,
修改为2次sql查询的python flask代码如下:
  1.     # get user goal from db
  2.     sql = 'SELECT name, distances from goals where DATE_FORMAT(date, "%Y%m") = DATE_FORMAT(CURDATE(), "%Y%m") '
  3.     cursor.execute(sql)
  4.     goals = [dict(name=row[0], distances=row[1]) for row in cursor.fetchall()]
  5.     app.logger.debug('index debug goals: %s', (goals))

  6.     # get current month record from db
  7.     sql = 'SELECT goals.name, goals.distances, DATE_FORMAT(records.date, "%e"), records.distance, records.pace, records.type \
  8.             FROM goals LEFT JOIN records ON goals.name = records.name \
  9.             where DATE_FORMAT(records.date, "%Y%m") = DATE_FORMAT(CURDATE(), "%Y%m") \
  10.             AND DATE_FORMAT(goals.date, "%Y%m") = DATE_FORMAT(CURDATE(), "%Y%m") \
  11.             ORDER by goals.name, records.date'
  12.     cursor.execute(sql)
  13.     records = [dict(name=row[0], distances=row[1], day=row[2], distance=row[3], pace=row[4], type=row[5]) for row in cursor.fetchall()]
  14.     app.logger.debug('index debug records: %s', (records))
  15.    
  16.     monthly = []
  17.     for goal in goals:
  18.         for d in range(1,32):
  19.             for record in records:
  20.                 if record.date == d:
  21.                     pass

  22.     #close db
  23.     close_db()
  24.     return render_template('index.html', monthly=monthly)
复制代码


求大神指点,谢谢!




您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:wangnan@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP