- 注意,这是一个被删除的问题的重写。我本来要编辑它,但没有评论,所以我甚至不知道它被删除,直到我今天去添加新的细节。*
- 背景 *:我正在修改我们的代码库,以使用多个数据库来验证用户提交的加载文件。这是为了自动检查用户数据,以便他们能够修复文件的简单问题,如检查唯一性等。
我们的原始代码(不是我写的)在加载时有一些根本性的问题。它有副作用。它应该使用transaction.atomic
,但是没有,简单地添加它破坏了代码库,所以虽然重构最终会正确地修复它,但是为了减少工作量...
- 问题 *:我创建了第二个数据库(别名为“validation”),并在代码中所有必要的地方插入了
.using(db)
和.save(using=db)
,这样就可以在不影响生产数据的情况下测试加载数据。
除了对full_clean()
的调用之外,2个数据库的一切工作都符合预期。
new_compound_dict = {
name="test",
formula="C1H4",
hmdb_id="HMBD0000001",
}
new_compound = Compound(**new_compound_dict)
new_compound.full_clean()
new_compound.save(using="validation")
它给我这个错误:
django.core.exceptions.ValidationError: {'name': ['Compound with this Name already exists.'], 'hmdb_id': ['Compound with this HMDB ID already exists.']}
我得到了相同的错误与此代码:
new_compound, inserted = Compound.objects.using("validation").get_or_create(**new_compound_dict)
if inserted:
new_compound.full_clean()
上面的两个示例在default
数据库上都没有问题。
我在django3.2的文档中查找了full_clean
,但是我没有找到一种方法让它在default
以外的数据库上运行。我想这是我需要做的来解决这个问题。甚至没有提到任何潜在的问题,与非默认数据库,我可以找到。我曾期望该文件显示有'是full_clean
的一个using
参数(类似于.save(using=db)
的参数),但是没有这样的参数。
在每个示例块之前和之后,我都使用以下代码调试了上面的示例:
Compound.objects.using("default").filter(**new_compound_dict).count()
Compound.objects.using("validation").filter(**new_compound_dict).count()
对于默认数据库,计数在没有错误之前为0,在没有错误之后为1。对于验证数据库,计数为0和1,但 * 带有 * 上述错误。
此时,我感到困惑。我如何在非默认数据库上运行full_clean
?full_clean是否根本不支持非默认数据库?
- 脚注:上例中的化合物上样量数据不会在用户提交中验证。化合物数据必须同时存在于两个数据库中,以便验证用户提交的数据。因此复合装载脚本是将数据装载到两个数据库中的两个脚本之一(这样当用户提交数据时它就在验证数据库中)默认加载总是在验证加载之前和加载验证数据库时发生,测试化合物始终存在于默认数据库中,并且仅在验证数据库中的验证加载之后才存在。*
1条答案
按热度按时间to94eoyn1#
根据Django Forum中乐于助人的用户Ken Whitesell的说法:
使用Model._default_manager执行模型的唯一测试。
他建议:
如果一个模型示例将与一个非默认数据库一起使用,那么您可能能够创建一个自定义管理器来检查该示例上的特定属性。
如果正在使用的函数向路由器提供了示例“提示”,那么您也可以使用定制路由器来检查示例。
因此,正如我所怀疑的,在Django中(至少在3.2.x中),您不能(没有自定义代码)使用非默认数据库运行
full_clean
。我没有完整的答案来解决这个问题,但我不再需要这样做,因为我已经接近
transaction.atomic
重构的结尾,以纠正促使我首先使用第二个数据库的底层问题。(早些时候),我再次遇到了这个问题,我只是想在这个问题上启发自己,因为我讨厌不理解为什么有些事情看起来应该不起作用。