首页 > 解决方案 > pytest/sqlalchemy 对象未绑定到会话错误

问题描述

我阅读了几篇类似我的问题的帖子,但没有发现任何相关内容。我有一个桌面应用程序,我尝试使用 pytest 执行一些测试。为此,我在 Docker 容器中运行 MySQL 服务器,并使用 sqlalchemy 构建会话以添加、更新等对象。但是我有这个错误我不知道如何解决sqlalchemy.orm.exc.DetachedInstanceError: Instance <Device at 0x7f4a38a01fd0> is not bound to a Session; attribute refresh operation cannot proceed

dspt.db.__init__.py

import os
from contextlib import contextmanager
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()
user = os.environ.get('MYSQL_USER')
pwd = os.environ.get('MYSQL_PWD')
url = os.environ.get('MYSQL_URL', 'localhost')
db_url = f"mysql+pymysql://{user}:{pwd}@{url}/db?charset=utf8mb4&binary_prefix=true"
print(db_url)
engine = create_engine(db_url, encoding='utf-8')
Session = scoped_session(sessionmaker(bind=engine))


@contextmanager
def db_session():
    """ Creates a SQLAlchemy session"""
    session = Session()
    try:
        yield session
        # session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.expunge_all()
        session.close()

测试.py

import pytest
from dspt.db import db_session, Base
from dspt.db.models import Device

@pytest.fixture(scope='session')
def get_device():
    return [Device(), Device(), Device()]


@pytest.fixture(scope='session')
def seed(get_device):
    devices = get_device
    with db_session() as session:
        for d in devices:
            session.add(d)
        session.commit()

def test_get_device(seed, get_device):
    with db_session() as session:
        devices = get_device
        res = session.query(Device)\
                     .filter(Device.serial == devices[0].serial)\
                     .all()

        assert len(res) == 1

标签: pythonsqlalchemypytest

解决方案


推荐阅读