gpt4 book ai didi

python - Django - 运行 "psycopg2.errors.ForeignKeyViolation: insert or update on table"时为 "python manage.py test",但运行单个测试时不是

转载 作者:行者123 更新时间:2023-12-05 05:52:11 28 4
gpt4 key购买 nike

所以我又发了一篇关于这个 issue 的帖子,我想我会进一步分解它,看看 StackOverflow 的好人是否能弄清楚发生了什么,因为我做不到。因此,我使用 setUpTestData 在下面生成了所有这些测试数据,一切看起来不错。我将调试器日志放在下面,以显示测试数据库中填充了预期的内容。当我进入测试 test_correct_num_posts_generated 时,测试本身通过了,但是我得到了这个奇怪的数据库错误。我把完整的错误输出放在下面。我已经通过多次测试得到了这个。我听说这可能与 Django 错误有关,测试数据库没有被正确拆除。这是一个奇怪的问题,因为当我运行 python manage.py test cheers.test.ExploreTest 它通过并且 python manage.py test cheers.test.ExploreTest.test_correct_num_posts_generated 它通过,但是当我运行 python manage.py test 时,出现如下所示的错误。这是怎么回事?

测试.pyPostFactory 是一个虚拟数据生成器。

@classmethod
def setUpTestData(cls) -> None:
cls.num_posts = 45
cls.health_cate = 'Health'
cls.fitness_cate = 'Fitness'
cls.relationship_cate = 'Relationship'
cls.goal_categories_name_list = [cls.health_cate, cls.fitness_cate, cls.relationship_cate]

cls.user = create_test_user_in_DB()
cls.access_token = get_test_user_access_token()
for name in cls.goal_categories_name_list:
goal_category_obj = GoalCategory.objects.create(name=name, emoji='Some URL')
goal_obj = Goal.objects.create(creator=cls.user, goal_category=goal_category_obj)
if name == cls.relationship_cate:
cls.relationship_join_goal = JoinGoal.objects.create(joiner=cls.user, goal=goal_obj,
status=GoalStatus.ONGOING)
else:
JoinGoal.objects.create(joiner=cls.user, goal=goal_obj, status=GoalStatus.ONGOING)

for i in range(cls.num_posts):
PostFactory()

调试器在 setUpTestData 结束时打印出来。当我到达 test_correct_num_posts_generated 时,所有这些也会打印出来。 >>> 是我输入的行,下面是打印输出。

>>>User.objects.all()
<QuerySet [<User 6badb4b8-33ba-4bb9-aa9a-2e3afb359960>]>
>>>GoalCategory.objects.all()
<QuerySet [<GoalCategory: GoalCategory object (Health)>, <GoalCategory: GoalCategory object (Fitness)>, <GoalCategory: GoalCategory object (Relationship)>]>
>>>len(Post.objects.all())
45
>>>JoinGoal.objects.all()
<QuerySet [<JoinGoal e7c4e4fa-3592-4ad9-b93a-245694a5e384>, <JoinGoal 7d637523-67db-4c59-aea6-37a8b43f0dd3>, <JoinGoal cbb954b7-332e-47f4-82e6-d2c77d874be5>]>

Test.py 中的测试失败

def test_correct_num_posts_generated(self):
self.assertTrue(len(Post.objects.all()), self.num_posts)

self.assertTrue(len(Post.objects.all()), self.num_posts) 通过了,但是这个测试抛出了我提到的臭名昭著的错误:

======================================================================
ERROR: test_correct_num_posts_generated (cheers.test.ExploreTests.ExploreFeedTest.ExploreFeedTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\envs\cheers\lib\site-packages\django\db\backends\utils.py", line 82, in _execute
return self.cursor.execute(sql)
psycopg2.errors.ForeignKeyViolation: insert or update on table "cheers_post" violates foreign key constraint "cheers_post_join_goal_id_da1e6957_fk_cheers_joingoal_uuid"
DETAIL: Key (join_goal_id)=(5c05a7d2-ff3c-4f1e-95d9-277ae164dabb) is not present in table "cheers_joingoal".


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\envs\cheers\lib\site-packages\django\test\testcases.py", line 284, in _setup_and_call
self._post_teardown()
File "C:\ProgramData\Anaconda3\envs\cheers\lib\site-packages\django\test\testcases.py", line 1006, in _post_teardown
self._fixture_teardown()
File "C:\ProgramData\Anaconda3\envs\cheers\lib\site-packages\django\test\testcases.py", line 1248, in _fixture_teardown
connections[db_name].check_constraints()
File "C:\ProgramData\Anaconda3\envs\cheers\lib\site-packages\django\db\backends\postgresql\base.py", line 285, in check_constraints
cursor.execute('SET CONSTRAINTS ALL IMMEDIATE')
File "C:\ProgramData\Anaconda3\envs\cheers\lib\site-packages\django\db\backends\utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\ProgramData\Anaconda3\envs\cheers\lib\site-packages\django\db\backends\utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:\ProgramData\Anaconda3\envs\cheers\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\ProgramData\Anaconda3\envs\cheers\lib\site-packages\django\db\utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\ProgramData\Anaconda3\envs\cheers\lib\site-packages\django\db\backends\utils.py", line 82, in _execute
return self.cursor.execute(sql)
django.db.utils.IntegrityError: insert or update on table "cheers_post" violates foreign key constraint "cheers_post_join_goal_id_da1e6957_fk_cheers_joingoal_uuid"
DETAIL: Key (join_goal_id)=(5c05a7d2-ff3c-4f1e-95d9-277ae164dabb) is not present in table "cheers_joingoal".

最佳答案

由于测试在 test cheers.test.ExploreTest 上通过,但在 test 上没有通过,因此肯定有一些来自其他包的测试弄乱了数据。

不确定这是否会解决问题,但由于您使用的是 Django 3.2,因此 docs 中有一个小注释:

Changed in Django 3.2:

Objects assigned to class attributes in setUpTestData() must supportcreating deep copies with copy.deepcopy() in order to isolate themfrom alterations performed by each test methods. In previous versionsof Django these objects were reused and changes made to them werepersisted between test methods.

使用 copy.deepcopy() 复制模型实例没有按预期工作,需要额外的步骤来创建新实例。我在文档中的任何地方都找不到它,但我使用了 this answer 中的代码多次(它适用于带有 Postgres 的 Django 3.2):

from copy import deepcopy
old_obj = deepcopy(obj)
old_obj.id = None
old_obj.save()

如果是这种情况,我将使用 setUp 而不是 setUpTestData,因为它会在每次测试之前重新创建测试数据库。
它速度较慢,您可能必须为某些测试更改特定数据,但它运行良好且更易于维护。

关于python - Django - 运行 "psycopg2.errors.ForeignKeyViolation: insert or update on table"时为 "python manage.py test",但运行单个测试时不是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70239770/

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