[Sqlalchemy-tickets] Issue #3950: 1.1 regression due to TypeDecorator copy() from Column.copy(), i
Brought to you by:
zzzeek
From: Michael B. <iss...@bi...> - 2017-03-30 21:19:37
|
New issue 3950: 1.1 regression due to TypeDecorator copy() from Column.copy(), interferes with mutable https://bitbucket.org/zzzeek/sqlalchemy/issues/3950/11-regression-due-to-typedecorator-copy Michael Bayer: this is a bug that exists since sqlalchemy.ext.mutable started, however it only is apparent when the type object is copied. The copy is uncommon except in the case of SchemaEventTarget, which TypeDecorator becomes in 1.1. ``` #!python from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base import json from sqlalchemy.ext import mutable Base = declarative_base() class MyType(TypeDecorator): impl = Text def process_bind_param(self, value, dialect): if value is not None: value = json.dumps(value) return value def process_result_value(self, value, dialect): if value is not None: value = json.loads(value) return value data = Column(mutable.MutableDict.as_mutable(MyType)) class A(Base): __tablename__ = 'a' id = Column(Integer, primary_key=True) # works fine # data = data # fails in 1.1 because TypeDecorator is a SchemaType, # so Column copies the type, so the event we attached # to scan mapper columns can't identify that this is the "data" # we copied data = data.copy() # as happens in declarative e = create_engine("sqlite://", echo=True) Base.metadata.create_all(e) s = Session(e) a1 = A(data={"foo": "bar"}) s.add(a1) s.commit() a1.data["foo"] = "bat" s.commit() assert a1.data["foo"] == "bat" ``` |