【问题标题】:SQLAlchemy revert auto_increment during testing (pytest)SQLAlchemy 在测试期间恢复 auto_increment (pytest)
【发布时间】:2018-04-01 04:49:19
【问题描述】:

我在conftest.py 中使用db_session 夹具

@pytest.fixture(scope='function')
def db_session(db, request):
    """Creates a new database session for a test."""
    engine = create_engine(DefaultConfig.SQLALCHEMY_DATABASE_URI, connect_args={"options": "-c timezone=utc"})
    DbSession = sessionmaker(bind=engine)
    session = DbSession()

    connection = engine.connect()
    transaction = connection.begin()

    options = dict(bind=connection, binds={})
    session = db.create_scoped_session(options=options)

    db.session = session

    yield session

    transaction.rollback()
    connection.close()
    session.remove()

在我的测试脚本test_project.py

import pytest
from package.model import Project

def test_create_project(db_session):
    project = Project(project_name="Test_Project")

    db_session.add(project)
    db_session.commit()

    assert project.project_id > 0
    assert project.project_id == 65 # supposed to be the next auto-increment value
    assert db_session.query(Project).filter_by(project_name="Test_Project").first() != None

每次我运行测试时,自动递增的主键都会增加。即使我使用db_session 夹具,主键序列也不会回滚。

我也尝试在测试之间调用db_session.begin_nested()db_session.rollback(),但主键仍然递增

def test_create_project(db_session):
    db_session.begin_nested()
    project = Project(project_name="Test_Project")

    db_session.add(project)
    db_session.commit()

    assert project.project_id > 0
    assert project.project_id == 65
    assert db_session.query(Project).filter_by(project_name="Test_Project").first() != None
    db_session.rollback()

如何在测试后恢复自增值?

环境

  • 数据库:PostgreSQL 9.6.5
  • 烧瓶 0.12.2
  • SQLAlchemy 1.1.12

【问题讨论】:

    标签: python postgresql sqlalchemy pytest


    【解决方案1】:

    使用 sqlalchemy 无法做到这一点。但是,您可以在所需的起点更改并重新启动序列。默认情况下,postgresql 将序列命名为<table_name>_<column_name>_seq。检查您的架构以找出序列名称。它是改变顺序所必需的。

    这里有一个小脚本来说明这一点:

    CREATE TABLE test(col1 SERIAL PRIMARY KEY, val TEXT);
    INSERT INTO test (val) VALUES ('abc'), ('def'), ('ghi');
    SELECT * FROM test;
    -- output
    1   abc
    2   def
    3   ghi
    
    DELETE FROM test WHERE col1 = 3;
    SELECT * FROM test;
    -- output
    1   abc
    2   def
    
    -- now alter the sequence so that the next insert gets value 3 in col1
    ALTER SEQUENCE test_col1_seq START 3 RESTART;
    INSERT INTO test (val) VALUES ('xyz');
    SELECT * FROM test;
    -- output
    1   abc
    2   def
    3   xyz
    

    【讨论】:

      【解决方案2】:
      session.execute('''ALTER SEQUENCE <table name>_<column name>_seq RESTART WITH <reset id>;''')
      

      尝试设置重置 id 以正确反映。

      参考:https://brianchildress.co/reset-auto-increment-in-postgres/

      【讨论】:

        猜你喜欢
        • 2022-10-05
        • 2014-09-28
        • 2019-10-04
        • 2020-05-27
        • 2018-05-25
        • 2021-04-18
        • 1970-01-01
        • 2023-04-05
        • 2018-05-09
        相关资源
        最近更新 更多