Python / Django:在MySQL数据库上模拟多维层

1 投票
4 回答
2180 浏览
提问于 2025-04-15 23:24

我正在做一个Django项目,需要对同一组数据提供很多不同的可视化展示(比如每个月的平均值、每年的平均值,或者某个地点的平均值等等)。

我在大学时用过一次OLAP数据库,觉得这可能适合我的需求,但实际上它对我来说太复杂了。其实我的数据量并不大,所以我不需要什么优化,只想找到一种方法,能展示同一组数据的不同可视化,而不需要写一千遍相同的代码。

所以,总结一下,我需要一个Python库:

  • 能够模拟一个多维数据库(OLAP风格的会很好,因为我觉得这种结构很方便:星型结构,等等)
  • 不干扰现有的MySQL数据库,因为我不能对它进行任何修改
  • 易于使用,因为如果不简单的话,换个工具也没什么意义。

4 个回答

0

你有 Python 的 defaultdict 字典。

如果你的数据量不大,可以直接把所有数据查询出来,然后用这些数据创建一些字典,里面存储计数、总和等等。

“星型模式”其实就是一种简单的数据库结构,适合预算有限的人使用。在这种结构中,维度(也就是字典)会指向一些行的列表。你可以对这些行的列表进行汇总,来创建汇总字典。

d1_sum= defaultdict( int )
d1_count= defaultdict( count )
d2_sum = defaultdict( int )
for row in MyFactTable.objects.all():
    d1_sum[row.attr1] += row.fact1
    d1_count[row.attr1] += 1
    d2_sum[row.attr2] += some_function( row.fact2 )
    etc.
1

为什么不直接使用标准的ORM聚合函数呢?可以参考这个链接:http://docs.djangoproject.com/en/dev/topics/db/aggregation/

如果你觉得某个字段的性能可能会受到影响,你可以考虑对这个字段进行去规范化处理。

2

好的……我终于想出了自己的解决办法(https://code.google.com/p/django-cube/),因为我找不到我想要的东西。

有一个这样的模型:

class Instrument(models.Model):
    name = models.CharField(max_length=100)

class Musician(models.Model):
    firstname = models.CharField(max_length=100)
    instrument = models.ForeignKey(Instrument)

创建一个立方体:

>>> c = Cube(['instrument__name', 'firstname'], Musician.objects.all(), len)
... #Cube(dimensions, queryset, aggregation_function)
... #You can use the Django field-lookup syntax for dates and foreign keys !!!

沿着一个(或多个)维度查询这个立方体:

>>> c.measure_dict('firstname', 'instrument__name', full=False) == {
...     'Miles': {
...         'trumpet': {'measure': 1},
...         'sax': {'measure': 0},
...         'piano': {'measure': 0},
...     },
...     'John': {
...         'trumpet': {'measure': 0},
...         'sax': {'measure': 1},
...         'piano': {'measure': 4},
...     },
... }

使用自定义的模板标签等等……

撰写回答