简体   繁体   English

Connection.commit() 不会在 Django 测试中保留数据

[英]Connection.commit() does not persist data in Django Test

I am attempting to test if my db_insert() method works.我正在尝试测试我的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))

This method is called by another method:这个方法被另一个方法调用:

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)

Lastly, the insert() method is invoked by a test in a TestCase subclass:最后,在TestCase子类中的测试调用insert()方法:

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]

The output in [1] does return 2 tuples. [1] 中的 output 确实返回 2 个元组。 These tuples however are data that have been added into the DB using models.save() in the setUp() .然而,这些元组是使用setUp() models.save()添加到数据库中的数据。

Can someone show me why conn.commit() is not persisting the data into the database as expected in a real run?有人可以告诉我为什么conn.commit()在实际运行中没有按预期将数据持久化到数据库中吗?

Your test is failing because it's running inside a Django TestCase .您的测试失败,因为它在 Django TestCase内运行。 That class uses transactions as a mechanism to run and then rollback tests. class 使用事务作为运行然后回滚测试的机制。 Since every test is run inside a transaction, any attempt to manually manage transactions within the test (such as your conn.commit() and conn.rollback() ) will wreak havoc.由于每个测试都在事务中运行,因此任何在测试中手动管理事务的尝试(例如您的conn.commit()conn.rollback() )都会造成严重破坏。

For tests like that that you should instead use TransactionTestCase .对于这样的测试,您应该改用TransactionTestCase That uses table truncation to undo database effects;使用表截断来撤消数据库影响; it's slower, but won't interfere with your ability to manage transactions.它速度较慢,但不会干扰您管理事务的能力。

See the documentation for more detail:有关更多详细信息,请参阅文档

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. Django 的TestCase class 是TransactionTestCase的一个更常用的子类,它利用数据库事务工具来加快在每个测试开始时将数据库重置为已知 state 的过程。 A consequence of this, however, is that some database behaviors cannot be tested within a Django TestCase class....然而,这样做的结果是某些数据库行为无法在TestCase测试用例 class 中进行测试。

A TransactionTestCase [unlike a TestCase ] may call commit and rollback and observe the effects of these calls on the database. TransactionTestCase [不像TestCase ] 可以调用 commit 和 rollback 并观察这些调用对数据库的影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 connection.commit()性能影响 - connection.commit() performance impact 即使使用 connection.commit() 也无法将数据提交到数据库(使用 Python flask MySQL) - Not able to Commit data to database (using Python flask MySQL) even after using connection.commit() Postgres:cursor.execute(“COMMIT”)与connection.commit() - Postgres: cursor.execute(“COMMIT”) vs. connection.commit() 从 pymysql 更频繁地使用 connection.commit() 到 AWS RDS 是否更昂贵? - Is using connection.commit() from pymysql more frequently to AWS RDS more expensive? 执行connection.commit()后,为什么其他cursor.execute()无法正常工作? - After execute connection.commit(), why the others cursor.execute() not work correctly? 如何从psycopg2 connection.commit()获取受影响的行数? - How can I get affected row count from psycopg2 connection.commit()? 任何人都可以告诉我python pyodbc中connection.commit()的意义是什么? - Can anyone tell me what' s the point of connection.commit() in python pyodbc ? 坚持Django FormView数据 - Persist Django FormView Data 如何使用 Django 在请求之间持久化数据 - How to persist data between requests using Django 为什么用空白数据发布的Django测试不起作用? - Why Django test with blank data post does not work?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM