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

14

大家好,我正在学习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))

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

异常类型:InternalError 异常值:当前事务已中止,在事务块结束之前被忽略的命令

这个错误的原因是什么?我认为可能是SQL语句出了问题,但最好的检查方法是什么?Django只提供了一个一般性的错误信息"Internal Error"。

谢谢你的帮助和建议!

1个回答

27

大多数情况下,这意味着前一个SQL语句执行失败。在这种情况下,您应该:

  1. 启用 SQL 日志记录,将以下片段粘贴到 settings.py 中:

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

  3. 再次运行 runserver,您应该可以在控制台中看到所有的 SQL 查询

  4. 直接在数据库中执行最后的 SQL 查询,然后您应该能够找出哪些查询失败并进行调试 - 或者开一个新问题,专门针对导致问题的查询。您可以使用 phpMyAdmin、直接的 CLI 客户端或任何数据库客户端,以逐个执行 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. 运行 runserver 并在浏览器中打开

你的控制台会像这样:

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=[]

1
您建议的SQL日志配置对我来说没有提供任何额外的控制台日志记录。 我已经将DEBUG = True,所以不确定还有什么其他方法可以实际查看SQL。 我在.extra()调用中出现了错误,我的where语句有一个拼写错误。 花了我几个小时才注意到它。 如果我能够看到我正在生成的SQL,那就轻而易举了。 我解决了我的问题,但Django确实没有帮助。 - gdonald
2
我给你的回答点赞,因为“在大多数情况下,这意味着前一个 SQL 语句未能执行。”恰好是我问题的原因。堆栈跟踪显示一个对象保存失败,但实际上是它上面的查询出了问题。以我的经验来看,在大多数情况下 Django 的堆栈跟踪并没有什么帮助。 - gdonald
我被“不提供任何额外的控制台日志记录”所困扰。因此,我更新了答案,包括一种测试此日志记录配置的简单方法。这样可以让您知道这是否来自您的项目(设置?)或环境。 - jpic
日志指令的重要部分(与默认的Django安装相比)是在“loggers”部分中设置'django': {{… 'level': 'DEBUG' …}}而不是'INFO' - jnns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接