python - Django QuerySet .count() 为 0 并且 .exists() 为 false,即使 QuerySet 中有一个对象(Django Rest Framework)

标签 python django amazon-web-services django-rest-framework amazon-rds

几个月来我一直有一个间歇性的错误,我被卡住了!帮助表示赞赏。

class ContentFile(models.Model):
    """
    Represents the metadata for a single document.
    """
    name = models.CharField(max_length=200)
    set = models.ForeignKey(Set, related_name='contentfile_set', on_delete=models.CASCADE)
    location = models.FileField(upload_to=get_content_file_upload_path)

    class Meta:
        app_label = 'ProtocolManager'
        unique_together = ('set', 'location')

    def __str__(self):
        return f"File {self.name} at location {str(self.location)} attached to {self.set}"


@receiver(models.signals.post_delete, sender=ContentFile)
def delete_file(sender, instance, *args, **kwargs):
    """
    Delete orphaned file once last ContentFile is removed.
    """
    log.info(f"Checking {instance.location} for existing ContentFile")
    if instance.location:
        from django.db import connection
        from django.db import reset_queries
        reset_queries()
        files_queryset = ContentFile.objects.filter(location=instance.location)
        if not files_queryset.exists():
            log.info(f"ContentFile does not exist for {instance.location}, deleting...")
            log.info(f"SQL: {connection.queries}")
            log.info(f"files_queryset: {list(files_queryset.all())}")
            log.info(f"count: {files_queryset.count()}")
            log.info(f"exists: {files_queryset.exists()}")
            instance.location.delete(save=False)
逻辑很简单。当 ContentFile 行被删除时,如果它是最后一个引用实际文件位置的行,我们会删除文件本身(在 AWS S3 上,如果重要的话)。这在 99% 的情况下按预期工作,但有时会失败,当它失败时,与给定 Set 关联的所有 ContentFiles 似乎都会失败。我添加了详细日志以试图获得更多线索,但今天它终于在几个月内首次重现并且日志令人沮丧:
...
2021-06-08 20:30:05,329 [INFO] ProtocolManager.models: Checking 1129/314.pdf for existing ContentFile
2021-06-08 20:30:05,335 [INFO] ProtocolManager.models: ContentFile does not exist for 1129/314.pdf, deleting...
2021-06-08 20:30:05,335 [INFO] ProtocolManager.models: SQL: [{'sql': "SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1129/314.pdf' LIMIT 1", 'time': '0.005'}]
2021-06-08 20:30:05,604 [INFO] ProtocolManager.models: files_queryset: [<ContentFile: File hypovolemic-traumatic-shockpdf.pdf at location 1129/314.pdf attached to Set v2021.6.8 '586-Joachim-Plattin Ambulance PCG' (1130-EDIT)>]
2021-06-08 20:30:05,610 [INFO] ProtocolManager.models: count: 0
2021-06-08 20:30:05,618 [INFO] ProtocolManager.models: exists: False
2021-06-08 20:30:05,685 [INFO] ProtocolManager.models: Checking 1116/312.pdf for existing ContentFile
2021-06-08 20:30:05,690 [INFO] ProtocolManager.models: Checking 1109/310.pdf for existing ContentFile
2021-06-08 20:30:05,700 [INFO] ProtocolManager.models: Checking 1101/306.pdf for existing ContentFile
2021-06-08 20:30:05,705 [INFO] ProtocolManager.models: Checking 1095/304.pdf for existing ContentFile
2021-06-08 20:30:05,711 [INFO] ProtocolManager.models: Checking 1089/301.pdf for existing ContentFile
2021-06-08 20:30:05,721 [INFO] ProtocolManager.models: Checking 1083/296.pdf for existing ContentFile
2021-06-08 20:30:05,726 [INFO] ProtocolManager.models: Checking 1080/292.pdf for existing ContentFile
2021-06-08 20:30:05,734 [INFO] ProtocolManager.models: Checking 1077/290.pdf for existing ContentFile
2021-06-08 20:30:05,739 [INFO] ProtocolManager.models: Checking 1075/289.pdf for existing ContentFile
2021-06-08 20:30:05,747 [INFO] ProtocolManager.models: Checking 1072/287.pdf for existing ContentFile
2021-06-08 20:30:05,754 [INFO] ProtocolManager.models: Checking 1066/285.pdf for existing ContentFile
2021-06-08 20:30:05,763 [INFO] ProtocolManager.models: Checking 1129/307.pdf for existing ContentFile
2021-06-08 20:30:05,768 [INFO] ProtocolManager.models: ContentFile does not exist for 1129/307.pdf, deleting...
2021-06-08 20:30:05,768 [INFO] ProtocolManager.models: SQL: [{'sql': "SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1129/307.pdf' LIMIT 1", 'time': '0.004'}]
2021-06-08 20:30:05,943 [INFO] ProtocolManager.models: files_queryset: [<ContentFile: File 0004-ift-medications.pdf at location 1129/307.pdf attached to Set v2021.6.8 '586-Joachim-Plattin Ambulance PCG' (1130-EDIT)>]
2021-06-08 20:30:05,947 [INFO] ProtocolManager.models: count: 0
2021-06-08 20:30:05,952 [INFO] ProtocolManager.models: exists: False
2021-06-08 20:30:05,982 [INFO] ProtocolManager.models: Checking 855/123.pdf for existing ContentFile
2021-06-08 20:30:05,987 [INFO] ProtocolManager.models: Checking 1096/122.pdf for existing ContentFile
2021-06-08 20:30:05,992 [INFO] ProtocolManager.models: Checking 855/121.pdf for existing ContentFile
2021-06-08 20:30:05,997 [INFO] ProtocolManager.models: Checking 1116/295.pdf for existing ContentFile
...
在日志中,它显示在相关位置实际上存在预期的 ContentFile 行(来自 list(files_queryset.all()) 的输出),但 count() 为 0 且 exists() 为假。
有谁知道为什么会发生这种情况?可能是 AWS RDS 的间歇性数据库问题?
同一时期的数据库日志(注意,为了清晰起见,我从上面的模型中删除了一些无关的字段,您仍然可以在数据库查询中看到它们):
2021-06-08 20:30:05,335 [DEBUG] django.db.backends: (0.005) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1129/314.pdf' LIMIT 1; args=('1129/314.pdf',)
2021-06-08 20:30:05,593 [DEBUG] django.db.backends: (0.257) SELECT `ProtocolManager_contentfile`.`id`, `ProtocolManager_contentfile`.`name`, `ProtocolManager_contentfile`.`set_id`, `ProtocolManager_contentfile`.`location`, `ProtocolManager_contentfile`.`extractedText`, `ProtocolManager_contentfile`.`pages`, `ProtocolManager_contentfile`.`md5`, `ProtocolManager_contentfile`.`fileSize`, `ProtocolManager_contentfile`.`createdOn`, `ProtocolManager_contentfile`.`createdBy_id`, `ProtocolManager_contentfile`.`lastUpdated`, `ProtocolManager_contentfile`.`updatedBy_id` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1129/314.pdf'; args=('1129/314.pdf',)
2021-06-08 20:30:05,602 [DEBUG] django.db.backends: (0.007) SELECT `ProtocolManager_set`.`id`, `ProtocolManager_set`.`setMeta_id`, `ProtocolManager_set`.`originSet_id`, `ProtocolManager_set`.`majorVersion`, `ProtocolManager_set`.`minorVersion`, `ProtocolManager_set`.`revisionVersion`, `ProtocolManager_set`.`acknowledgmentSetID`, `ProtocolManager_set`.`receiptAckText`, `ProtocolManager_set`.`pubLevel`, `ProtocolManager_set`.`minOSiOS`, `ProtocolManager_set`.`minOSAndroid`, `ProtocolManager_set`.`minVersioniOS`, `ProtocolManager_set`.`minVersionAndroid`, `ProtocolManager_set`.`createdOn`, `ProtocolManager_set`.`createdBy_id`, `ProtocolManager_set`.`lastUpdated`, `ProtocolManager_set`.`updatedBy_id` FROM `ProtocolManager_set` WHERE `ProtocolManager_set`.`id` = 1130 LIMIT 21; args=(1130,)
2021-06-08 20:30:05,604 [DEBUG] django.db.backends: (0.001) SELECT `ProtocolManager_setmeta`.`id`, `ProtocolManager_setmeta`.`region_id`, `ProtocolManager_setmeta`.`setName`, `ProtocolManager_setmeta`.`displayName`, `ProtocolManager_setmeta`.`isOffline`, `ProtocolManager_setmeta`.`offlineReason`, `ProtocolManager_setmeta`.`discontinued`, `ProtocolManager_setmeta`.`invisible`, `ProtocolManager_setmeta`.`isSponsored`, `ProtocolManager_setmeta`.`isOutdated`, `ProtocolManager_setmeta`.`lastUID`, `ProtocolManager_setmeta`.`companyNumberLabel`, `ProtocolManager_setmeta`.`companyNumberRegex`, `ProtocolManager_setmeta`.`customBundleId`, `ProtocolManager_setmeta`.`betaEnabled`, `ProtocolManager_setmeta`.`restrictedMD5`, `ProtocolManager_setmeta`.`createdOn`, `ProtocolManager_setmeta`.`lastUpdated`, `ProtocolManager_setmeta`.`createdBy_id`, `ProtocolManager_setmeta`.`updatedBy_id` FROM `ProtocolManager_setmeta` WHERE `ProtocolManager_setmeta`.`id` = 586 LIMIT 21; args=(586,)
2021-06-08 20:30:05,610 [DEBUG] django.db.backends: (0.005) SELECT COUNT(*) AS `__count` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1129/314.pdf'; args=('1129/314.pdf',)
2021-06-08 20:30:05,617 [DEBUG] django.db.backends: (0.007) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1129/314.pdf' LIMIT 1; args=('1129/314.pdf',)
2021-06-08 20:30:05,690 [DEBUG] django.db.backends: (0.004) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1116/312.pdf' LIMIT 1; args=('1116/312.pdf',)
2021-06-08 20:30:05,700 [DEBUG] django.db.backends: (0.009) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1109/310.pdf' LIMIT 1; args=('1109/310.pdf',)
2021-06-08 20:30:05,705 [DEBUG] django.db.backends: (0.004) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1101/306.pdf' LIMIT 1; args=('1101/306.pdf',)
2021-06-08 20:30:05,711 [DEBUG] django.db.backends: (0.006) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1095/304.pdf' LIMIT 1; args=('1095/304.pdf',)
2021-06-08 20:30:05,721 [DEBUG] django.db.backends: (0.009) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1089/301.pdf' LIMIT 1; args=('1089/301.pdf',)
2021-06-08 20:30:05,725 [DEBUG] django.db.backends: (0.004) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1083/296.pdf' LIMIT 1; args=('1083/296.pdf',)
2021-06-08 20:30:05,734 [DEBUG] django.db.backends: (0.008) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1080/292.pdf' LIMIT 1; args=('1080/292.pdf',)
2021-06-08 20:30:05,739 [DEBUG] django.db.backends: (0.004) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1077/290.pdf' LIMIT 1; args=('1077/290.pdf',)
2021-06-08 20:30:05,746 [DEBUG] django.db.backends: (0.007) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1075/289.pdf' LIMIT 1; args=('1075/289.pdf',)
2021-06-08 20:30:05,754 [DEBUG] django.db.backends: (0.007) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1072/287.pdf' LIMIT 1; args=('1072/287.pdf',)
2021-06-08 20:30:05,762 [DEBUG] django.db.backends: (0.007) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1066/285.pdf' LIMIT 1; args=('1066/285.pdf',)
2021-06-08 20:30:05,767 [DEBUG] django.db.backends: (0.004) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1129/307.pdf' LIMIT 1; args=('1129/307.pdf',)
2021-06-08 20:30:05,937 [DEBUG] django.db.backends: (0.169) SELECT `ProtocolManager_contentfile`.`id`, `ProtocolManager_contentfile`.`name`, `ProtocolManager_contentfile`.`set_id`, `ProtocolManager_contentfile`.`location`, `ProtocolManager_contentfile`.`extractedText`, `ProtocolManager_contentfile`.`pages`, `ProtocolManager_contentfile`.`md5`, `ProtocolManager_contentfile`.`fileSize`, `ProtocolManager_contentfile`.`createdOn`, `ProtocolManager_contentfile`.`createdBy_id`, `ProtocolManager_contentfile`.`lastUpdated`, `ProtocolManager_contentfile`.`updatedBy_id` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1129/307.pdf'; args=('1129/307.pdf',)
2021-06-08 20:30:05,940 [DEBUG] django.db.backends: (0.001) SELECT `ProtocolManager_set`.`id`, `ProtocolManager_set`.`setMeta_id`, `ProtocolManager_set`.`originSet_id`, `ProtocolManager_set`.`majorVersion`, `ProtocolManager_set`.`minorVersion`, `ProtocolManager_set`.`revisionVersion`, `ProtocolManager_set`.`acknowledgmentSetID`, `ProtocolManager_set`.`receiptAckText`, `ProtocolManager_set`.`pubLevel`, `ProtocolManager_set`.`minOSiOS`, `ProtocolManager_set`.`minOSAndroid`, `ProtocolManager_set`.`minVersioniOS`, `ProtocolManager_set`.`minVersionAndroid`, `ProtocolManager_set`.`createdOn`, `ProtocolManager_set`.`createdBy_id`, `ProtocolManager_set`.`lastUpdated`, `ProtocolManager_set`.`updatedBy_id` FROM `ProtocolManager_set` WHERE `ProtocolManager_set`.`id` = 1130 LIMIT 21; args=(1130,)
2021-06-08 20:30:05,942 [DEBUG] django.db.backends: (0.001) SELECT `ProtocolManager_setmeta`.`id`, `ProtocolManager_setmeta`.`region_id`, `ProtocolManager_setmeta`.`setName`, `ProtocolManager_setmeta`.`displayName`, `ProtocolManager_setmeta`.`isOffline`, `ProtocolManager_setmeta`.`offlineReason`, `ProtocolManager_setmeta`.`discontinued`, `ProtocolManager_setmeta`.`invisible`, `ProtocolManager_setmeta`.`isSponsored`, `ProtocolManager_setmeta`.`isOutdated`, `ProtocolManager_setmeta`.`lastUID`, `ProtocolManager_setmeta`.`companyNumberLabel`, `ProtocolManager_setmeta`.`companyNumberRegex`, `ProtocolManager_setmeta`.`customBundleId`, `ProtocolManager_setmeta`.`betaEnabled`, `ProtocolManager_setmeta`.`restrictedMD5`, `ProtocolManager_setmeta`.`createdOn`, `ProtocolManager_setmeta`.`lastUpdated`, `ProtocolManager_setmeta`.`createdBy_id`, `ProtocolManager_setmeta`.`updatedBy_id` FROM `ProtocolManager_setmeta` WHERE `ProtocolManager_setmeta`.`id` = 586 LIMIT 21; args=(586,)
2021-06-08 20:30:05,947 [DEBUG] django.db.backends: (0.004) SELECT COUNT(*) AS `__count` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1129/307.pdf'; args=('1129/307.pdf',)
2021-06-08 20:30:05,952 [DEBUG] django.db.backends: (0.004) SELECT (1) AS `a` FROM `ProtocolManager_contentfile` WHERE `ProtocolManager_contentfile`.`location` = '1129/307.pdf' LIMIT 1; args=('1129/307.pdf',)

最佳答案

您可能在 ProtocolManager_contentfile 上有一个损坏的索引。 table 。
This question似乎一直在处理类似的现象。如果这是您的问题的原因,您可能需要 REINDEX你的数据库。

关于python - Django QuerySet .count() 为 0 并且 .exists() 为 false,即使 QuerySet 中有一个对象(Django Rest Framework),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67895800/

相关文章:

python - 在没有 GPU 支持的 MacOS 上安装 cupy

python - python 中的 3D 卷积

php - 使用 iOS 设备连接到 sql 或 oracle 服务器

amazon-web-services - 有没有办法从 CFT 中的 DNS 名称获取 HostedZoneId?

python - Pandas DataFrame 将 json 列列表转换为信息行,每 "id"

python - ClientForm.AmbiguityError : more than one control matching name

python - 如何在 Django 中创建复杂的 Left JOIN

amazon-web-services - AWS ECS上的Kafka,如何在没有已知实例的情况下处理advertised.host?

django - 领头启动时出现 ImportError : No module named my_project. wsgi 错误

python - 我可以使用 django-storages 和 boto 将 ImageField 直接从 Django 管理上传到 S3 吗?