Python 从sqlite迁移到postgres(django)时如何更新unittests
我有一个很大的Django项目,有很多视图/模型。我最近将我的项目从sqlite3迁移到本地postgres,并计划进一步扩展(将postgres放在单独的机器上,等等) 当我从sqlite迁移到postgres时,我遵循了这一点,它似乎工作得非常完美。(也就是说,我的跑步应用程序看起来与数据库使用sqlite时完全相同) 我的问题是:当我运行以前编写的单元测试时,第一个单元测试工作正常,所有正在进行的单元测试都失败。单独而言,单元测试工作良好。我在stackoverflow上看到了一些解决这个问题的方法,但是解决方案还不清楚。如何为我的单元测试重新编写Python 从sqlite迁移到postgres(django)时如何更新unittests,python,django,postgresql,python-unittest,pytest-django,Python,Django,Postgresql,Python Unittest,Pytest Django,我有一个很大的Django项目,有很多视图/模型。我最近将我的项目从sqlite3迁移到本地postgres,并计划进一步扩展(将postgres放在单独的机器上,等等) 当我从sqlite迁移到postgres时,我遵循了这一点,它似乎工作得非常完美。(也就是说,我的跑步应用程序看起来与数据库使用sqlite时完全相同) 我的问题是:当我运行以前编写的单元测试时,第一个单元测试工作正常,所有正在进行的单元测试都失败。单独而言,单元测试工作良好。我在stackoverflow上看到了一些解决这个
setUp()
/teardown()
方法,以便它们与我新迁移的postgres db一起通过?我需要完全重写所有单元测试吗
我已经看到了,尽管我不完全确定如何基于此修改我的单元测试
我的测试套件是用测试视图的不同类设置的。那么比如说,
class View1Tests(TestCase):
def setUp(self):
c1 = Category.objects.create(id=55555, leaf_node_name="Test Category 1")
c2 = Category.objects.create(id=12345, leaf_node_name="Test Category 2")
s1 = Search.objects.create(category=c1, username="testuser")
s2 = Search.objects.create(category=c2, username="testuser2")
def test_view1_success(self):
#blablabla
def test_view1_fail(self):
#blablabla
def test_view1_something(self):
#blablabla
我遇到如下错误:
appname.models.DoesNotExist:搜索匹配查询不存在
同样,当sqlite3是db时,所有这些单元测试都运行得非常好。我认为这是一个问题的postgres测试设置?但我甚至不知道从哪里开始。任何帮助都将不胜感激 我想我终于解决了这个问题。当尝试使用默认主键(例如,
MyModel.objects.get(pk=1)
,MyModel.objects.get(id=1)
)获取对象时,会出现此问题。我的假设是Postgres使用串行数据类型作为自动字段,增量的值取决于Postgres生成的序列
我找到的解决方案非常简单。通过具有该对象唯一属性的属性获取,或者使用列表索引获取所有对象并进行筛选。后一种方法不应该太麻烦,因为在大多数情况下,会创建一些模型实例
这里有一个完整的例子
可能是一个愚蠢的问题,但您的测试类可能扩展了
django.test.TestCase
,并且您正在使用python manage.py test
?WillKeeling我的测试扩展了django.test.TestCase。但是,我正在运行pytest
来运行所有测试。运行python manage.py测试也会抛出相同的错误。@HeidiLyons:您解决了这个问题吗?我现在也在同一个地方。如果你能发布对你有用的东西,那就太好了!谢谢。从sqlite迁移到postgresql时,我也遇到了同样的错误。如果我发现了问题所在,我会发布回复。解决方案张贴在下面。为什么会发生这种情况?我有一个问题。。。我想测试补丁和删除需要提供模型id的方法。我该如何测试这个,id是随机的。以前,我使用的是sqlite,但在迁移到postgres后,这些测试开始失败。@GoutamBSeervi正如我在回答中提到的,使用列表索引来获取记录,而不是按ID获取。这应该允许您测试其他方法。这是一项大量的工作。。我得重写我所有的测试。我已经被这个错误困扰了一天,现在我可以通过用TransactionTestCase替换TestCase来解决这个问题,现在我的测试工作正常了……但是现在它们需要更多的时间。xD以前大约需要一秒钟,现在是70秒
# models.py
class Book(models.Model):
isbn = models.CharField(
max_length=13,
primary_key=True # uniqueness is enforced
)
book_name = models.CharField(
max_length=128,
unique=True # another unique field
)
author_count = models.IntegerField()
book_genre = models.CharField(max_length=64)
# tests.py
class MyTest(TestCase):
@classmethod
def setUpTestData(cls):
# first object
Book.objects.create(
isbn='10101',
book_name='Binary Code',
author_count=1,
book_genre='Fiction'
)
# second object
Book.objects.create(
isbn='314159',
book_name='Life of Pi',
author_count=1,
book_genre='Philosophy'
)
def setUp(self):
self.book1 = Book.objects.all()[0]
# or self.book1 = Book.objects.get(isbn='10101')
# or self.book1 = Book.objects.get(book_name='Binary Code')
self.book2 = Book.objects.all()[1]
# or self.book2 = Book.objects.get(isbn='314159')
# or self.book2 = Book.objects.get(book_name='Life of Pi')
def test_something(self):
# lastly, since `setUp` is called before every test_* method
# you can just access the instance's attributes without calling `get`
# e.g:
self.assertEqual(self.book1.book_genre, 'Fiction')
def test_something_else(self):
# you an also reload the instance using `refresh_from_db`
# after making changes
Book.objects.filter(author_count=1).update(book_genre='Fiction')
self.book2.refresh_from_db()
self.assertEqual(self.book2.book_genre, 'Fiction')