【问题标题】:Using Peewee ORM to generate data for graphs使用 Peewee ORM 为图生成数据
【发布时间】:2014-12-15 05:49:06
【问题描述】:

我正在构建一个网络应用程序,它允许教授输入作业供学生跟随,如果你愿意的话,还有一个交互式教学大纲。课程页面的其中一个部分显示进度。

我已经构建了一个饼图组件,我想用数据填充它:

pie_chart(
    title, # name of chart
    percent, # percentage of assignments completed
    count, # how many assignments completed
    total # how many assignments total
)

我正在使用 Peewee ORM 从我的分配表中检索这些数据:

class Type(BaseModel):
    name = CharField() # Homework, Test, Final, etc.

class Assignment(BaseModel):
    name = CharField()
    due_date = DateField()
    type = ForeignKeyField(Type)
    course = ForeignKeyField(Course)

我需要数据库中的以下内容,但我不确定如何使用 Peewee 来完成它。获取名称和总数应该很简单。但我需要将due_date 与今天的日期进行比较,以查看完成了多少作业。

已完成的姓名总数

决赛 2 0 家庭作业 23 12 测试 4 2

如果重要的话,我的饼图输出将如下所示:

Homework
|XXX-------|
3 of 10 complete

更新

我有一个查询几乎可以满足我的所有需求。谁能帮我完成剩下的工作?

这是查询:

select t.name,
        count(a.type_id) as total,
        (
            select count(id)
            from assignment a
            where a.course_id = 7
            and a.user_id = 3
            and a.due_date < date()
            group by a.type_id
            order by a.type_id
        ) as completed
from assignment a
inner join type t on t.id = a.type_id
where a.course_id = 7
and a.user_id = 3
group by a.type_id
order by a.type_id

以下是使用以下示例数据得出的结果:

Homework, 8, 6
Test, 4, 6
Final, 2, 6

这真的很接近,但我希望完成的列特定于分配类型。

这是分配表中的一些示例数据

id name
------------------------
9, Chapter 1, 2014-11-01
10, Chapter 2, 2014-11-08
11, Test on chapter 1-2, 2014-11-15
12, Chapter 3, 2014-11-19
13, Chapter 4, 2014-11-22
14, Test on chapter 3-4, 2014-11-25
15, Midterm - Chapter 1-4, 2014-11-25
16, Chapter 5, 2014-11-25
17, Chapter 6, 2014-11-25
18, Test on chapter 5-6, 2014-11-25
19, Chapter 7, 2015-01-09
20, Chapter 8, 2015-01-11
21, Test on chapter 7-8, 2015-01-13
22, Final - Chapter 1-8, 2015-01-15

以下是我目前能想到的最好的。我正在对“已完成”列进行硬编码,因为我无法正确处理:

Assignment.select(
    Type.name,
    fn.Lower('1').alias('completed'),
    fn.Count(Type.id).alias('total'),
).join(Type).where(
    Assignment.course==self,
).group_by(Type.id).order_by(Type.id)

【问题讨论】:

    标签: python sql orm peewee


    【解决方案1】:

    我认为您的问题是您的子查询返回不止一行 - 您应该将 'and a.type_id = t.id' 添加到子查询的 where。

    【讨论】:

    • 冉,感谢您指出这一点,这确实解决了这个问题!不过,我宁愿避免使用子查询。您对我如何做到这一点有什么想法吗?
    【解决方案2】:

    python 中的日期(尤其是 peewee)的优点在于您可以以非常直观的方式比较它们。在幕后日期通常表示为自 1970 年某个日期以来的秒数。以下是使用 peewee 按日期查询的示例:

    today = datetime.today()
    query = Tweet.update(is_published=True).where(Tweet.creation_date < today)
    query.execute()
    

    在此示例中,Tweet 类只是一个具有布尔值is_published 属性和日期时间creation_date 属性的类。

    更接近您的示例的是:

    today = datetime.today()
    query = Assignment.select().where(Assignment.due_date < today)
    

    但我会尽量不完全给出答案。

    希望对您有所帮助,如果您有任何问题,请告诉我。

    【讨论】:

      【解决方案3】:

      如果您在 python 值中没有今天方便的值(并且您正在使用 sqlite),您可以使用fn.date('now') 来获取今天。 MySQL 或 Postgresql 也存在类似的函数。

      【讨论】:

      • 所以我想弄清楚的部分内容是如何最好地获得总价值和已经通过的价值。
      • 我不确定我知道这意味着什么。
      • 对不起科尔。我意识到缺乏细节。我需要获取给定类型的“总”分配数量,以及已经发生的分配数量。使用上面的示例,我需要确定在今天之前发生了 3 个作业,并且总共有 10 个作业。我不确定实现这一目标的最佳方法。也许是子查询?
      猜你喜欢
      • 2018-05-28
      • 1970-01-01
      • 1970-01-01
      • 2018-07-19
      • 1970-01-01
      • 2016-06-11
      • 2016-03-06
      • 1970-01-01
      • 2017-03-26
      相关资源
      最近更新 更多