如何调试:内部错误当前事务已中止,命令被忽略直到事务块结束

14 投票
1 回答
9759 浏览
提问于 2025-04-17 11:57

大家好,

我刚开始接触GeoDjango,想找一些更好的方法来检查错误的SQL语句。

到目前为止,我只是想把一个经纬度点保存到我的PostgreSQL表里。

我的模型是这样定义的:

    geolocation = models.PointField(_('Geo Location'), 
                geography=True, 
                null = True, 
                blank = True,
                help_text=_('Geolocation with Longitude and Latitude'))

    objects = models.GeoManager()

在我的视图中,我尝试执行以下命令:

savedProject.geolocation = GEOSGeometry('POINT(%s %s)' %(u_lng,u_lat))

但是当我尝试保存表单时,收到了以下错误:

异常类型:内部错误 异常信息:当前事务已中止,命令在事务块结束之前会被忽略

这个错误的原因是什么呢?我觉得SQL语句可能有问题,但检查的最佳方法是什么?Django只给出了一个通用的错误信息“内部错误”。

谢谢大家的帮助和建议!

1 个回答

27

在大多数情况下,这意味着之前的 SQL 语句执行失败了。在这种情况下,你应该:

  1. 启用 SQL 日志记录,可以参考下面的代码片段,把它粘贴到 settings.py 文件中

  2. 设置 DEBUG=1,否则 SQL 日志不会被记录

  3. 再次运行 runserver,你应该能在控制台看到所有的 SQL 查询

  4. 直接在你的数据库中执行最后的 SQL 查询,这样你就能找到哪些查询失败了,然后你可以调试它们,或者提出一个新的问题,专门针对导致问题的查询。你可以使用 phpMyAdmin,或者直接用命令行客户端,或者其他任何数据库客户端,逐个执行 SQL 查询,直到找到需要修复的那一个。

SQL 日志记录配置:

LOGGING = { 
   'version': 1,
   'disable_existing_loggers': True,
   'formatters': {
       'simple': {
           'format': '%(levelname)s %(message)s',
       },  
   },  
   'handlers': {
       'console':{
           'level':'DEBUG',
           'class':'logging.StreamHandler',
           'formatter': 'simple'
       },  
   },  
   'loggers': {
       'django': {
           'handlers': ['console'],
           'level': 'DEBUG',
       },  
   }   
}

如果这个配置在使用 runserver 时没有提供额外的控制台输出,你可以尝试 django-autocomplete-light 的示例测试项目

  1. 阅读并粘贴安装命令到 /tmp 目录

  2. 切换到 autocomplete_light_env/src/django-autocomplete-light/test_project 目录

  3. 打开 test_project/settings.py,用上面的 LOGGING 配置替换原来的

  4. 运行服务器并打开你的浏览器

你的控制台看起来会像:

Validating models...

0 errors found
Django version 1.4.1, using settings 'test_project.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
DEBUG (0.001) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."model" = taggable  AND "django_content_type"."app_label" = charfield_autocomplete ); args=('taggable', 'charfield_autocomplete')
DEBUG (0.000) 
        SELECT DISTINCT "tagging_tag".id, "tagging_tag".name
        FROM
            "tagging_tag"
            INNER JOIN "tagging_taggeditem"
                ON "tagging_tag".id = "tagging_taggeditem".tag_id
            INNER JOIN "charfield_autocomplete_taggable"
                ON "tagging_taggeditem".object_id = "charfield_autocomplete_taggable"."id"

        WHERE "tagging_taggeditem".content_type_id = 11

        GROUP BY "tagging_tag".id, "tagging_tag".name

        ORDER BY "tagging_tag".name ASC; args=[]

撰写回答