RawQuerySet中不支持类似select_related的功能
我在使用Django 1.3的时候遇到了一个问题,关于原始SQL查询。当我用ORM的select_related()方法时,可以一次性从数据库获取到所有需要的数据。
activities = UserActivity.objects.filter(Q(user__in=friends_list),Q(activity_type = UserActivity.TYPE_POST, post__status=Post.PUBLIC_STATUS)|Q(activity_type = UserActivity.TYPE_SHORT_REVIEW)|Q(activity_type = UserActivity.TYPE_COMMENT)).select_related()
上面的例子让我只需要与数据库建立一次连接。
[{'time': '0.164', 'sql': 'SELECT "useractivity_useractivity"."id", "useractivity_useractivity"."activity_type", "useractivity_useractivity"."status", "useractivity_useractivity"."permalink", "useractivity_useractivity"."user_id", "useractivity_useractivity"."username", "useractivity_useractivity"."object_id", "useractivity_useractivity"."watching_object_id", "useractivity_useractivity"."post_id", "useractivity_useractivity"."short_review_id", "useractivity_useractivity"."comment_id", "useractivity_useractivity"."link_id", "useractivity_useractivity"."film_id", "useractivity_useractivity"."checkin_id", "useractivity_useractivity"."title", "useractivity_useractivity"."content", "useractivity_useractivity"."film_title", "useractivity_useractivity"."film_permalink", "useractivity_useractivity"."url", "useractivity_useractivity"."url_kind", "useractivity_useractivity"."video_thumb", "useractivity_useractivity"."spoilers", "useractivity_useractivity"."is_first_post", "useractivity_useractivity"."number_of_comments", "useractivity_useractivity"."channel_name", "useractivity_useractivity"."channel_id", "useractivity_useractivity"."checkin_date", "useractivity_useractivity"."rating", "useractivity_useractivity"."featured", "useractivity_useractivity"."modified_at", "useractivity_useractivity"."created_at", "useractivity_useractivity"."LANG", "useractivity_useractivity"."is_sent", "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "useractivity_useractivity" INNER JOIN "auth_user" ON ("useractivity_useractivity"."user_id" = "auth_user"."id") LEFT OUTER JOIN "blog_post" ON ("useractivity_useractivity"."post_id" = "blog_post"."parent_id") LEFT OUTER JOIN "core_object" ON ("blog_post"."parent_id" = "core_object"."id") WHERE ("useractivity_useractivity"."LANG" = E\'en\' AND "useractivity_useractivity"."user_id" IN (10, 16, 12, 14, 6, 32, 13, 40, 4, 15, 47, 5, 50, 51, 53, 33, 24, 22, 153, 208, 207, 65, 23, 398, 203, 312, 582, 402, 416, 30, 144, 979, 173, 133, 690, 1748, 38, 2104, 1918, 1989, 1850, 1788, 2389, 395, 2535, 2658, 2287, 953, 2845, 2790, 2849, 3016, 2656, 3114, 3190, 156, 2981, 3193, 2884, 193, 445, 3742, 1069, 4035, 4178, 2568, 1409, 2292, 3561, 4801, 162, 4968, 4090, 4916, 4548, 5213, 2878, 5208, 3120, 4294, 5406, 5944, 6221, 6266, 6305, 3559, 3577, 2846, 2580, 2416, 970, 6969, 7126, 7175, 6401, 5237, 172, 792, 17, 7246, 1779, 134, 6433, 3725, 6343, 2121, 4193, 721, 958, 375, 2875, 6124, 754, 137, 241, 219, 540, 337, 152, 955, 6717, 6808, 7121, 2752, 6802, 6793, 5146, 4183, 7349, 7375, 6452, 284, 6544, 4276, 7377, 7387, 151, 7314, 7357, 1373, 7397, 6260, 500, 7437, 4961, 7478, 4559, 7545, 7554, 7555, 7488, 7092, 4615, 7285, 7619, 7621, 7344, 6409, 422, 7686) AND (("core_object"."status" = 1 AND "useractivity_useractivity"."activity_type" = 1 ) OR "useractivity_useractivity"."activity_type" = 2 OR "useractivity_useractivity"."activity_type" = 3 ))'}]
但是,当我尝试把同样的查询放到原始SQL中时:
activity = UserActivity.objects.raw(query)
list(activity)
我却得到了几千个查询请求到数据库,比如:
SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 4801
看起来RawQuerySet并没有一次性获取所有数据,而是每次调用friends_list的时候,都会去数据库查询用户的权限。
为什么RawQuerySet的表现和select_related不一样,尽管执行的是相同的查询呢?
1 个回答
0
好的。问题不在我的查询上,而是跟打印结果有关。这个函数试图打印的是 user,而不是 username,所以每次都得从数据库里获取 user。
之前是这样
def __unicode__(self):
return "%s" % self.user
现在应该是这样
def __unicode__(self):
return self.username