Connection.commit() 不在 Django 测试中保留数据
Connection.commit() does not persist data in Django Test
我正在尝试测试我的 db_insert()
方法是否有效。
def db_insert(data, insert_query, limit=100):
"""Persist data to database
:param data: Tuple of tuples
:param insert_query: String
:param limit: Integer
"""
# Insert / Merge
cursor = conn.cursor()
try:
for i in range(0, int(len(data) / limit) + 1):
sliced_data = data[i * limit:i * limit + limit]
if sliced_data:
cursor.executemany(insert_query, sliced_data)
conn.commit()
except Exception as e:
conn.rollback()
raise DBException('ScriptName:db_manager.py,ErrorType:{}Impact:Unable to insert into database,'
'ErrorMessage:{}'.format(type(e).__name__, e))
此方法被另一个方法调用:
def insert(cls, new_list):
"""Insert new data to DB
:param new_list: List
"""
try:
insert_query = "insert into TABLE {} values {}" \
.format(tuple(cls.TABLE_ATTR[1:]), ('%s',) * len(cls.TABLE_ATTR[1:]))
insert_query = insert_query.replace('\'', '')
db_insert(new_list, insert_query)
except Exception as e:
logger.exception(e)
最后,insert()
方法由 TestCase
子类中的测试调用:
def test_insert_method_success(self):
SomeModule.insert(['text1', 'text2', 'text3', 1, settings.SCRIPT_RUN_TIME])
cursor = conn.cursor()
cursor.execute("select * from TABLE")
data = cursor.fetchall()
print(data) # [1]
[1] 中的输出执行 return 2 个元组。但是,这些元组是使用 setUp()
.
中的 models.save()
添加到数据库中的数据
谁能告诉我为什么 conn.commit()
没有像预期的那样在真实的 运行 中将数据持久保存到数据库中?
你的测试失败了,因为它运行在 Django TestCase
中。 class 使用事务作为 运行 的机制,然后进行回滚测试。由于每个测试都在事务中 运行,任何在测试中手动管理事务的尝试(例如您的 conn.commit()
和 conn.rollback()
)都会造成严重破坏。
对于这样的测试,您应该改用 TransactionTestCase
。使用 table t运行cation 来撤销数据库效果;它速度较慢,但不会影响您管理事务的能力。
有关详细信息,请参阅 the documentation:
Django’s TestCase
class is a more commonly used subclass of TransactionTestCase
that makes use of database transaction facilities to speed up the process of resetting the database to a known state at the beginning of each test. A consequence of this, however, is that some database behaviors cannot be tested within a Django TestCase
class....
A TransactionTestCase
[unlike a TestCase
] may call commit and rollback and observe the effects of these calls on the database.
我正在尝试测试我的 db_insert()
方法是否有效。
def db_insert(data, insert_query, limit=100):
"""Persist data to database
:param data: Tuple of tuples
:param insert_query: String
:param limit: Integer
"""
# Insert / Merge
cursor = conn.cursor()
try:
for i in range(0, int(len(data) / limit) + 1):
sliced_data = data[i * limit:i * limit + limit]
if sliced_data:
cursor.executemany(insert_query, sliced_data)
conn.commit()
except Exception as e:
conn.rollback()
raise DBException('ScriptName:db_manager.py,ErrorType:{}Impact:Unable to insert into database,'
'ErrorMessage:{}'.format(type(e).__name__, e))
此方法被另一个方法调用:
def insert(cls, new_list):
"""Insert new data to DB
:param new_list: List
"""
try:
insert_query = "insert into TABLE {} values {}" \
.format(tuple(cls.TABLE_ATTR[1:]), ('%s',) * len(cls.TABLE_ATTR[1:]))
insert_query = insert_query.replace('\'', '')
db_insert(new_list, insert_query)
except Exception as e:
logger.exception(e)
最后,insert()
方法由 TestCase
子类中的测试调用:
def test_insert_method_success(self):
SomeModule.insert(['text1', 'text2', 'text3', 1, settings.SCRIPT_RUN_TIME])
cursor = conn.cursor()
cursor.execute("select * from TABLE")
data = cursor.fetchall()
print(data) # [1]
[1] 中的输出执行 return 2 个元组。但是,这些元组是使用 setUp()
.
models.save()
添加到数据库中的数据
谁能告诉我为什么 conn.commit()
没有像预期的那样在真实的 运行 中将数据持久保存到数据库中?
你的测试失败了,因为它运行在 Django TestCase
中。 class 使用事务作为 运行 的机制,然后进行回滚测试。由于每个测试都在事务中 运行,任何在测试中手动管理事务的尝试(例如您的 conn.commit()
和 conn.rollback()
)都会造成严重破坏。
对于这样的测试,您应该改用 TransactionTestCase
。使用 table t运行cation 来撤销数据库效果;它速度较慢,但不会影响您管理事务的能力。
有关详细信息,请参阅 the documentation:
Django’s
TestCase
class is a more commonly used subclass ofTransactionTestCase
that makes use of database transaction facilities to speed up the process of resetting the database to a known state at the beginning of each test. A consequence of this, however, is that some database behaviors cannot be tested within a DjangoTestCase
class....A
TransactionTestCase
[unlike aTestCase
] may call commit and rollback and observe the effects of these calls on the database.