fix test suite under SQLAlchemy 1.2.x

* SQLAlchemy 1.0 introduced "baked queries" - a way to construct Query
 objects so that they can be cached and reused.

 * SQLAlchemy 1.2 changed lazyloaded columns to use baked queries under the
 hood.

 * Our MultilangQuery class attempts to set _default_language_id right
 before the query is executed by overriding the __iter__ method.

 * Baked queries bypass the __iter__ method and call a lower-level
 method, _execute_and_instances, directly.

 * This caused problems where _default_language_id wouldn't get set
 correctly on lazyloaded columns.

 * To fix, make MultilangQuery override the _execute_and_instances
 method instead of __iter__.

 * This is really just a stopgap: the root cause is that query params
 are not preserved across lazyloads.

Tested with SQLAlchemy 0.9.7, 1.1.18, and 1.2.5.

Updates #236.
This commit is contained in:
Andrew Ekstedt 2018-03-30 12:01:21 -07:00
parent 5f15698876
commit e1bbe78b72

View file

@ -207,11 +207,13 @@ def create_translation_table(_table_name, foreign_class, relation_name,
return Translations return Translations
class MultilangQuery(Query): class MultilangQuery(Query):
def __iter__(self): def _execute_and_instances(self, *args, **kwargs):
# Set _default_language_id param if it hasn't been set by the time the query is executed.
# XXX This is really hacky and we should figure out a cleaner method.
if '_default_language_id' not in self._params or self._params['_default_language_id'] == 'dummy': if '_default_language_id' not in self._params or self._params['_default_language_id'] == 'dummy':
self._params = self._params.copy() self._params = self._params.copy()
self._params['_default_language_id'] = self.session.default_language_id self._params['_default_language_id'] = self.session.default_language_id
return super(MultilangQuery, self).__iter__() return super(MultilangQuery, self)._execute_and_instances(*args, **kwargs)
class MultilangSession(Session): class MultilangSession(Session):
"""A tiny Session subclass that adds support for a default language. """A tiny Session subclass that adds support for a default language.