social-app-flask-sqlalchemy
の問題を診断しようとしているときに、予期しない動作やバグがあるかどうかわからないところで、やや直感的な振る舞いを見つけました。mixinの変更可能な列が突然変異を追跡しない
は、次のコードを考えてみましょう:
from sqlalchemy import create_engine, Column, Integer, PickleType
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.mutable import MutableDict
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class A(Base):
__abstract__ = True
class B(Base):
id = Column(Integer, primary_key=True)
__tablename__ = 'some_table'
my_data = Column(MutableDict.as_mutable(PickleType))
class C(A, B):
pass
engine = create_engine('sqlite://')
session_factory = sessionmaker(bind=engine)
db_session = session_factory()
Base.metadata.create_all(engine)
assert B.my_data.type.__class__ is PickleType
c_instance = C(my_data={'foo': 'bar'})
db_session.add(c_instance)
db_session.commit()
loaded_instance = db_session.query(C).first()
loaded_instance.my_data.update(baz=1)
assert loaded_instance.my_data['baz'] == 1
assert loaded_instance in db_session.dirty
これは問題なく動作します。ここでのB
のスーパークラスをobject
に変更すると、最後のアサーションエラーが出力されます。そこまで、すべてがうまくいく。
それはB
サブクラスを持っていないことにより、直接、my_data
の種類がもはやMutableDict
ことを強制されdeclarative_base
ことが判明していないが、オブジェクト(この場合はdict
)をインスタンス化するときに我々が与えるどんなタイプ。明らかに、これはmy_data
への変更がもはや追跡されないことを意味する。ただし、my_data
はデータ型としてPickleType
を使用しているため、すぐには表示されません。
extra_data
への変更がsocial-app-flask-sqlalchemy
にDBに書き込まれていないと、もともと私はこれに遭遇しました。 social-app-flask-sqlalchemy
は、列を保持するSQLAlchemyUserMixin
クラスがサブクラス化されていないdeclarative_base
クラスですが、そのサブクラスUserSocialAuth
は、_AppSession
を経由しています。
今、問題として報告する場所がわかりません。sqlalchemy
またはsocial-app-flask-sqlalchemy
です。何かご意見は?
、[Iは '社会ストレージsqlalchemy'が固定されるべきであると信じて(HTTPS失敗単純な宣言と
declared_attr
両方の例://github.com/python-social-auth/social-storage-sqlalchemy/blob/master/social_sqlalchemy/storage.py#L90)、ひどい名前のモデルではない場合。彼らには[commit-flush](https://github.com/python-social-auth/social-storage-sqlalchemy/blob/master/social_sqlalchemy/storage.py#L64)などの他の面白いパターンもあります。これは冗長でなければなりません[とにかく最初にフラッシュします](http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.commit)場合。 –