如何消除额外的重复查询?

时间:2016-05-18 10:45:23

标签: python django django-rest-framework query-optimization django-queryset

我正在尝试的是在使用Django Rest Framework序列化查询集时优化对查询集进行的查询。

模型分布在不同的应用程序上。 JSONObject mainJsonObject; @Override public Object handleRequest(Object input, Context context) { inputHashMap = (LinkedHashMap) input; responseJSON = new ResponseJSON(); mainJsonObject = new JSONObject(); saveDataToDynamoDB(inputHashMap); return mainJsonObject; } public void saveDataToDynamoDB(LinkedHashMap inHashMap){ String login_id = (String) inputHashMap.get("login_id"); String first_name = (String) inputHashMap.get("first_name"); String last_name = (String) inputHashMap.get("last_name"); try{ DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient()); Table tableUserDetails = dynamoDB.getTable(USER_PROFILE_TABLE); Item userProfileTableItem = new Item().withPrimaryKey("login_id", login_id) .withString("first_name", first_name).withString("last_name", last_name); tableUserDetails.putItem(userProfileTableItem); mainJsonObject.put("status", "Success"); mainJsonObject.put("message", "Profile saved successfully."); mainJsonObject.put("login_id", login_id); mainJsonObject.put("first_name", first_name); mainJsonObject.put("last_name", last_name); }catch(Exception e){ try { mainJsonObject.put("status", "Failed"); mainJsonObject.put("message", "Failed to saved profile data."); } catch (JSONException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }

AbstractModels

以及 #core.abstractmodels class BasicModelMixin(models.Model): name = models.CharField(max_length=255) slug = AutoSlugField(max_length=265, unique=True, populate_from='name') class Meta: abstract = True #core.abstractmodels class ExtraBaseModel(models.Model): software_license = models.ManyToManyField('meta.License') class Meta: abstract = True 应用上的 Language 类,

languages

其许可证字段继承自 #languages.models class Language(BasicModelMixin, ExtraBaseModel): name = models.CharField(max_length=255, unique=True) slug = AutoSlugField(max_length=265, unique=True, populate_from='name') releases = models.ManyToManyField( 'languages.LanguageRelease', blank=True, related_name="%(app_label)s_%(class)s_related_releases", related_query_name="%(app_label)s_%(class)ss_releases")

ExtraBaseModel

当我查询 #meta.License class License(BasicModelMixin): display_name = models.CharField(max_length=25) 对象时,会产生额外的重复查询,我需要消除这些查询。

查询如下,

Language

将查询缩短为4毫秒,其中2个是重复的。 django-debug-toolbar的输出是,

Language.objects.filter(pk=1).prefetch_related('software_license')

如何优化查询?必须对模型进行哪些更改才能使其最小化?

Django版本= 1.9.x | python版本:2.7.11 | db:sqlite

更新: 序列化程序(因为我只关注ManyToMany关系而被删除。),

SELECT *** FROM "languages_language" WHERE "languages_language"."slug" = '''python'''

SELECT *** FROM "meta_license" INNER JOIN
"languages_language_software_license" ON
("meta_license"."id" 
= "languages_language_software_license"."license_id") 
WHERE
"languages_language_software_license"."language_id"

SELECT *** FROM "meta_license"
Duplicated 2 times. 

SELECT *** FROM "meta_license"
Duplicated 2 times.

查询跟踪,

class LanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Language
        fields = ('software_license',)

2 个答案:

答案 0 :(得分:0)

BrowsableAPI通常会显示重复的查询,因为将为创建/更新表单独立查询相关字段。

您可以通过将django.db.backend添加到日志记录配置并将内容类型设置为JSON或使用只读权限(禁用表单)来打开Django数据库查询日志记录。

请注意,有时候,Django Debug工具栏有时会根据它们的评估方式重复查询(虽然我不记得导致它的确切条件,但我已经被这个查询了。)

答案 1 :(得分:0)

meta.License

编写单独的序列化程序
class LicenseSerializer(serializers.ModelSerializer):
    class Meta:
        model = License
        fields = '__all__' # choose the fields you wish

然后修改序列化程序

class LanguageSerializer(serializers.ModelSerializer):
    software_license = LicenseSerializer(many=True) # make sure you match field name
    class Meta:
        model = Language
        fields = ('software_license',)