[英]Unable to Instantiate Python Dataclass (Frozen) inside a Pytest function that uses Fixtures
我正在关注 Harry Percival 和 Bob Gregory 在 Python 中的架构模式。
在第三 (3) 章左右,他们介绍了测试 SQLAlchemy 的 ORM。
一个需要session
夹具的新测试,由于cannot assign to field '_sa_instance_state'
而AttributeError, FrozenInstanceError
可能需要注意的是,其他测试在创建OrderLine
实例时不会失败,但如果我只是将session
包含到测试参数中,它们就会失败。
无论如何,我会直接进入代码。
conftest.py
@pytest.fixture
def local_db():
engine = create_engine('sqlite:///:memory:')
metadata.create_all(engine)
return engine
@pytest.fixture
def session(local_db):
start_mappers()
yield sessionmaker(bind=local_db)()
clear_mappers()
model.py
@dataclass(frozen=True)
class OrderLine:
id: str
sku: str
quantity: int
test_orm.py
def test_orderline_mapper_can_load_lines(session):
session.execute(
'INSERT INTO order_lines (order_id, sku, quantity) VALUES '
'("order1", "RED-CHAIR", 12),'
'("order1", "RED-TABLE", 13),'
'("order2", "BLUE-LIPSTICK", 14)'
)
expected = [
model.OrderLine("order1", "RED-CHAIR", 12),
model.OrderLine("order1", "RED-TABLE", 13),
model.OrderLine("order2", "BLUE-LIPSTICK", 14),
]
assert session.query(model.OrderLine).all() == expected
pipenv run pytest test_orm.py
的控制台错误
============================= test session starts =============================
platform linux -- Python 3.7.6, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: /home/[redacted]/Documents/architecture-patterns-python
collected 1 item
test_orm.py F [100%]
================================== FAILURES ===================================
____________________ test_orderline_mapper_can_load_lines _____________________
session = <sqlalchemy.orm.session.Session object at 0x7fd919ac5bd0>
def test_orderline_mapper_can_load_lines(session):
session.execute(
'INSERT INTO order_lines (order_id, sku, quantity) VALUES '
'("order1", "RED-CHAIR", 12),'
'("order1", "RED-TABLE", 13),'
'("order2", "BLUE-LIPSTICK", 14)'
)
expected = [
> model.OrderLine("order1", "RED-CHAIR", 12),
model.OrderLine("order1", "RED-TABLE", 13),
model.OrderLine("order2", "BLUE-LIPSTICK", 14),
]
test_orm.py:13:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
<string>:2: in __init__
???
../../.local/share/virtualenvs/architecture-patterns-python-Qi2y0bev/lib64/python3.7/site-packages/sqlalchemy/orm/instrumentation.py:377: in _new_state_if_none
self._state_setter(instance, state)
<string>:1: in set
???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'OrderLine' object has no attribute '_sa_instance_state'") raised in repr()] OrderLine object at 0x7fd919a8cf50>
name = '_sa_instance_state'
value = <sqlalchemy.orm.state.InstanceState object at 0x7fd9198f7490>
> ???
E dataclasses.FrozenInstanceError: cannot assign to field '_sa_instance_state'
<string>:4: FrozenInstanceError
=========================== short test summary info ===========================
FAILED test_orm.py::test_orderline_mapper_can_load_lines - dataclasses.Froze...
============================== 1 failed in 0.06s ==============================
附加问题
我理解上面的逻辑以及这些文件在做什么,但如果我缺乏基本的理解,请纠正我。
conftest.py
(used for all pytest config) is setting up a session
fixture, which basically sets up a temporary database in memory - using start and clear mappers to ensure that the orm model definitions are binding to the db isntance.model.py
只是一个用于表示原子OrderLine
object 的数据类。test_orm.py
class 用于 pytest 以提供session
夹具,以便显式setup, execute, teardown
数据库以运行测试。我正在关注 Harry Percival 和 Bob Gregory 在 Python 中的架构模式。
在第三 (3) 章左右,他们介绍了测试 SQLAlchemy 的 ORM。
一个需要session
夹具的新测试,由于cannot assign to field '_sa_instance_state'
而AttributeError, FrozenInstanceError
可能需要注意的是,其他测试在创建OrderLine
实例时不会失败,但如果我只是将session
包含到测试参数中,它们就会失败。
无论如何,我会直接进入代码。
conftest.py
@pytest.fixture
def local_db():
engine = create_engine('sqlite:///:memory:')
metadata.create_all(engine)
return engine
@pytest.fixture
def session(local_db):
start_mappers()
yield sessionmaker(bind=local_db)()
clear_mappers()
model.py
@dataclass(frozen=True)
class OrderLine:
id: str
sku: str
quantity: int
test_orm.py
def test_orderline_mapper_can_load_lines(session):
session.execute(
'INSERT INTO order_lines (order_id, sku, quantity) VALUES '
'("order1", "RED-CHAIR", 12),'
'("order1", "RED-TABLE", 13),'
'("order2", "BLUE-LIPSTICK", 14)'
)
expected = [
model.OrderLine("order1", "RED-CHAIR", 12),
model.OrderLine("order1", "RED-TABLE", 13),
model.OrderLine("order2", "BLUE-LIPSTICK", 14),
]
assert session.query(model.OrderLine).all() == expected
pipenv run pytest test_orm.py
的控制台错误
============================= test session starts =============================
platform linux -- Python 3.7.6, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: /home/[redacted]/Documents/architecture-patterns-python
collected 1 item
test_orm.py F [100%]
================================== FAILURES ===================================
____________________ test_orderline_mapper_can_load_lines _____________________
session = <sqlalchemy.orm.session.Session object at 0x7fd919ac5bd0>
def test_orderline_mapper_can_load_lines(session):
session.execute(
'INSERT INTO order_lines (order_id, sku, quantity) VALUES '
'("order1", "RED-CHAIR", 12),'
'("order1", "RED-TABLE", 13),'
'("order2", "BLUE-LIPSTICK", 14)'
)
expected = [
> model.OrderLine("order1", "RED-CHAIR", 12),
model.OrderLine("order1", "RED-TABLE", 13),
model.OrderLine("order2", "BLUE-LIPSTICK", 14),
]
test_orm.py:13:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
<string>:2: in __init__
???
../../.local/share/virtualenvs/architecture-patterns-python-Qi2y0bev/lib64/python3.7/site-packages/sqlalchemy/orm/instrumentation.py:377: in _new_state_if_none
self._state_setter(instance, state)
<string>:1: in set
???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'OrderLine' object has no attribute '_sa_instance_state'") raised in repr()] OrderLine object at 0x7fd919a8cf50>
name = '_sa_instance_state'
value = <sqlalchemy.orm.state.InstanceState object at 0x7fd9198f7490>
> ???
E dataclasses.FrozenInstanceError: cannot assign to field '_sa_instance_state'
<string>:4: FrozenInstanceError
=========================== short test summary info ===========================
FAILED test_orm.py::test_orderline_mapper_can_load_lines - dataclasses.Froze...
============================== 1 failed in 0.06s ==============================
附加问题
我理解上面的逻辑以及这些文件在做什么,但如果我缺乏基本的理解,请纠正我。
1. conftest.py
(used for all pytest config) is setting up a session
fixture, which basically sets up a temporary database in memory - using start and clear mappers to ensure that the orm model definitions are binding to the db isntance.
2. model.py
只是一个用于表示原子OrderLine
object 的数据类。
3. test_orm.py
class for pytest 提供session
夹具,为了setup, execute, teardown
一个运行测试的数据库。
从版本 1.14.16 开始,
def dispose(self, class_):`
必须改为
def unregister(self, class_, manager):`
````
https://github.com/sqlalchemy/sqlalchemy/compare/rel_1_4_15...rel_1_4_16#diff-fc3d434dae3b60f8b2b448ee1e24165ffa71e75fbb2aeef1b4651e678a095be7R223
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.