Question: I'm following along with Architecture Patterns in Python by Harry Percival and Bob Gregory. Around chapter three (3) they introduce testing the ORM of SQLAlchemy. A new test that requires a session fixture, it is throwing AttributeError, FrozenInstanceError due to cannot assign to field '_sa_instance_state' It may be important to note that other tests do not fail when creating instances of OrderLine, but they do fail if I simply include session into the test parameter(s). Anyway I'll get straight into the code. 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  Console error for 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 ==============================  Additional Questions I understand the overlying logic and what these files are doing, but correct my if my rudimentary understanding is lacking.  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 simply a dataclass used to represent an atomic OrderLine object. test_orm.py class for pytest to supply the session fixture, in order to setup, execute, teardown a db explicitly for the purpose of running tests.  Issue resolution provided by https://github.com/cosmicpython/code/issues/17

Answer: SqlAlchemy allows you to override some of the attribute instrumentation that is applied when using mapping classes and tables. In particular the following allows sqla to save the state on an instrumented frozen dataclass. This should be applied before calling the mapper function which associates the dataclass and the sql table. from sqlalchemy.ext.instrumentation import InstrumentationManager ... DEL_ATTR = object() class FrozenDataclassInstrumentationManager(InstrumentationManager): def install_member(self, class_, key, implementation): self.originals.setdefault(key, class_.__dict__.get(key, DEL_ATTR)) setattr(class_, key, implementation) def uninstall_member(self, class_, key): original = self.originals.pop(key, None) if original is not DEL_ATTR: setattr(class_, key, original) else: delattr(class_, key) def dispose(self, class_): del self.originals delattr(class_, "_sa_class_manager") def manager_getter(self, class_): def get(cls): return cls.__dict__["_sa_class_manager"] return get def manage(self, class_, manager): self.originals = {} setattr(class_, "_sa_class_manager", manager) def get_instance_dict(self, class_, instance): return instance.__dict__ def install_state(self, class_, instance, state): instance.__dict__["state"] = state def remove_state(self, class_, instance, state): del instance.__dict__["state"] def state_getter(self, class_): def find(instance): return instance.__dict__["state"] return find OrderLine.__sa_instrumentation_manager__ = FrozenDataclassInstrumentationManager   Attribute instrumentation docs Custom instrumentation examples