I am using SQLAlchemy with Alembic to simplify access to the database that I am using and any changes to the data structure that I make for tables. This works very well until I began to notice more and more problems with the "expiring" SQLAlchemy fields from my point of view, almost by accident.
An example is this snippet,
class HRDecimal(Model):
dec_id = Column(String(50), index=True)
@staticmethod
def qfilter(*filters):
"""
:rtype : list[HRDecimal]
"""
return list(HRDecimal.query.filter(*filters))
class Meta(Model):
dec_id = Column(String(50), index=True)
@staticmethod
def qfilter(*filters):
"""
:rtype : list[Meta]
"""
return list(Meta.query.filter(*filters))
the code:
ids = ['1', '2', '3']
decs = HRDecimal.qfilter(
HRDecimal.dec_id.in_(ids))
metas = Meta.qfilter(
Meta.dec_id.in_(ids))
combined = []
for ident in ids:
combined.append((
ident,
[dec for dec in decs if dec.dec_id == ident],
[hm for hm in metas if hm.dec_id == ident]
))
There were no problems for the above, but when I process a list of identifiers that can contain several thousand identifiers, this process has worked for a huge amount of time, and if it is made from a web request into a flask, the thread is often killed.
When I started to peep why this was happening, the key area was
[dec for dec in decs if dec.dec_id == ident],
[hm for hm in metas if hm.dec_id == ident]
- ( ) Python, - dec.dec_id hm.dec_id, SQLAlchemy, ,
def __get__(self, instance, owner):
if instance is None:
return self
dict_ = instance_dict(instance)
if self._supports_population and self.key in dict_:
return dict_[self.key]
else:
return self.impl.get(instance_state(instance), dict_)
InstrumentedAttribute sqlalchemy/orm/attributes.py, , , , ,
def get(self, state, dict_, passive=PASSIVE_OFF):
"""Retrieve a value from the given object.
If a callable is assembled on this object attribute, and
passive is False, the callable will be executed and the
resulting value will be set as the new value for this attribute.
"""
if self.key in dict_:
return dict_[self.key]
else:
key = self.key
if key not in state.committed_state or \
state.committed_state[key] is NEVER_SET:
if not passive & CALLABLES_OK:
return PASSIVE_NO_RESULT
if key in state.expired_attributes:
value = state._load_expired(state, passive)
Of AttributeImpl . , state._load_expired SQL-. , , , , "" SQL- , , , "" .
, session-options,
app = Flask(__name__)
CsrfProtect(app)
db = SQLAlchemy(app)
app = Flask(__name__)
CsrfProtect(app)
db = SQLAlchemy(
app,
session_options=dict(autoflush=False, autocommit=False, expire_on_commit=False))
, , , , , , , ( ) , "" SQLAlchemy - , .
- SQLAlchemy, "" Python, , , , ?