gpt4 book ai didi

python - IntegrityError 中缺少表名(Django ORM)

转载 作者:太空狗 更新时间:2023-10-29 20:48:57 25 4
gpt4 key购买 nike

我在 Django 的 IntegrityError 中缺少表名:

Traceback (most recent call last):
...
return self.cursor.execute(sql, params)
File ".../django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File ".../django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
IntegrityError: null value in column "manager_slug" violates not-null constraint
DETAIL: Failing row contains (17485, null, 2017-10-10 09:32:19, , 306).

有没有办法查看 INSERT/UPDATE 正在访问哪个表?

我们使用 PostgreSQL 9.6。

这是一个一般性问题:如何获得更好的错误信息?

这不是关于这个特定专栏的问题。很快就找到了相关的表格和专栏。但我想改进来 self 们 CI 系统的错误消息。下次我想立即看到表名。

我知道,如果我在软件开发过程中看到此错误,我可以使用调试器轻松揭示缺失的信息。但在我的例子中,这发生在生产中,我只有上面的堆栈跟踪。

最佳答案

此回溯中的异常消息是来自数据库驱动程序的原始消息。如果有任何内容被谷歌搜索、报告等,了解这一点和回溯很有用。

所有后端的异常类都是相同的 django.db.utils.IntegrityError,但消息或参数取决于后端:

  • postgres:“manager_slug”列中的空值违反了非空约束\n DETAILS...\n
  • mysql . . : (1048, "列 'manager_slug' 不能为 null")
  • sqlite3 。 : NOT NULL 约束失败:appname_modelname.manager_slug

表名仅在 sqlite3 后端可见。一些后端仅使用异常的字符串参数,但 mysql 使用两个参数:数字错误代码和消息。 (我愿意接受这是一个一般性问题,不仅是 PostgreSQL。)一些后端的作者希望应用程序的作者直接或从 SQL 知道表名,但对于一般的 ORM 包来说并非如此。即使在技术上可以做到完美,也没有更好的和普遍接受的方式来扩展消息。

开发调试简单:

  • 在开发中的 DEBUG 模式下可以使用许多附加信息(最后一帧中的“SQL”或“myobj.save()”等行中的对象的类名)
  • python manage.py test --debug-sql:“打印失败时记录的 SQL 查询。”
  • 使用 sqlite3 开发/测试中的相同错误更易于阅读。

...但您可能要求在生产中出现运行时错误。

我猜你在一个如此笼统的问题中可能的意图,你可能对哪个方向感兴趣。

A) traceback 中最重要的信息通常是许多行之上的几行".../django/db/...”。这对古鲁来说是非常容易的。如果代码不像 Django 管理站点那样动态和通用,则很有可能使用它,其中 myobj.save() 调用附近的代码(父框架中都不包含)不包含显式模型名称。示例:

# skip some initial universal code in ".../django/..."
...
# our apps start to be interesting... (maybe other installed app)
...
# START HERE: Open this line in the editor. If the function is universal, jump to the previous.
File ".../me/app/...py", line 47, in my...
my_obj.save()
# skip many stack frames .../django/db/... below
File ".../django/db/models/base.py", line 734, in save
# self.save_base(... # this line 733 is not visible
force_update=force_update, update_fields=update_fields)
...
# interesting only sql and params, but not visible in production
File ".../django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
IntegrityError (or DataError similarly)...

B) 通过模型的共同祖先获取信息

class ...(models.Model):
def save(self, *args, **wkargs):
try:
super(..., self).save(*args, **wkargs)
except django.db.utils.IntegrityError as exc:
new_message = 'table {}'.format(self._meta.db_table)
exc.extra_info = new_message
# this is less compatible, but it doesn't require additional reading support
# exc.args = exc.args + (new_message,)
reraise

这可能会使多重继承的调试复杂化。

C) 在 Django db 中的实现 会更好,但我无法想象它会被接受并且在出现问题后不会恢复。

关于python - IntegrityError 中缺少表名(Django ORM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46661147/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com