如何在Django中注释/聚合字符串字段

时间:2012-01-24 15:12:04

标签: python sql django

我有一个复杂的数据集,如果通过原始SQL获取将涉及大量连接并做奇怪的事情,比如在字符串字段上使用聚合器函数:

SELECT
    "trainer_trainer"."user_id",
    "trainer_trainer"."email",
    "trainer_trainer"."background",
    "trainer_trainer"."history",
    "trainer_trainer"."manualrating",
    COUNT("trainer_helperqueue"."id") AS "available",
    MAX("account_account"."photo") AS "photo",
    COUNT("trainer_trainersession"."id") AS "busy",
    MAX("account_account"."name") AS "name"
FROM
    "trainer_trainer"
LEFT OUTER JOIN
    "auth_user" ON ("trainer_trainer"."user_id" = "auth_user"."id")
LEFT OUTER JOIN
    "trainer_helperqueue" ON ("auth_user"."id" = "trainer_helperqueue"."user_id")
LEFT OUTER JOIN
    "account_account" ON ("auth_user"."id" = "account_account"."user_id")
LEFT OUTER JOIN
    "trainer_trainersession" ON ("auth_user"."id" = "trainer_trainersession"."helper_id")
GROUP BY
    "trainer_trainer"."user_id",
    "trainer_trainer"."email",
    "trainer_trainer"."background",
    "trainer_trainer"."history",
    "trainer_trainer"."manualrating",
    "trainer_trainer"."user_id",
    "trainer_trainer"."email",
    "trainer_trainer"."background",
    "trainer_trainer"."history",
    "trainer_trainer"."manualrating"

这个查询实际上运行得很好,但是Django在尝试处理结果时会在内部爆炸:

Trainer.objects.annotate(
    photo=Max("user__account__photo"),
    name=Max("user__account__name"),
    available=Count("user__assistance_providing"),
    busy=Count("user__helping")
)

ValueError: invalid literal for float(): path/to/photo.jpg

这是追溯的尾端:

PROJECTROOT/virtualenv/lib/python2.6/site-packages/django/db/models/sql/compiler.pyc in results_iter(self)
    705                         for (alias, aggregate), value
    706                         in zip(self.query.aggregate_select.items(), row[aggregate_start:aggregate_end])
    --> 707                     ]) + tuple(row[aggregate_end:])
    708 
    709                 yield row

PROJECTROOT/virtualenv/lib/python2.6/site-packages/django/db/models/sql/query.pyc in resolve_aggregate(self, value, aggregate, connection)
    320         else:
    321             # Return value depends on the type of the field being processed.

--> 322             return self.convert_values(value, aggregate.field, connection)
    323 
    324     def get_aggregation(self, using):

PROJECTROOT/virtualenv/lib/python2.6/site-packages/django/db/models/sql/query.pyc in convert_values(self, value, field, connection)
    298         it can be overridden by Query classes for specific backends.
    299         """
--> 300         return connection.ops.convert_values(value, field)
    301 
    302     def resolve_aggregate(self, value, aggregate, connection):

PROJECTROOT/virtualenv/lib/python2.6/site-packages/django/db/backends/__init__.pyc in convert_values(self, value, field)
    742         # No field, or the field isn't known to be a decimal or integer

    743         # Default to a float

--> 744         return float(value)
    745 
    746     def check_aggregate_support(self, aggregate_func):

ValueError:float()的文字无效:photos / 4/8/7/201120124111455-487767.jpg

怪异的是,SQL查询就在那里?它直接来自db.connection.queries。 Django运行它,它在数据库级别工作,然后Django撤销处理结果。

我是否应该不使用.annotate()非数字函数?有更好/更聪明的方式吗?

0 个答案:

没有答案