From 95cf16a6a0521a5bd78222f847953e6c7dd6fbe6 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 13 Apr 2011 18:43:34 +0300 Subject: [PATCH] Make pokedex work with SQLAlchemy 0.7. Warning: ugly hack! In its quest to reduce the number of calls, SQLAlchemy 0.7 sometimes bypasses session.execute, where the _default_language_id bound parameter was set. Monkeypatching the connection works for now, but I hope there's a better way (see multilang.py). --- pokedex/db/load.py | 1 - pokedex/db/markdown.py | 4 ++-- pokedex/db/multilang.py | 27 ++++++++++++++++----------- setup.py | 2 +- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/pokedex/db/load.py b/pokedex/db/load.py index d307fd8..d0dc00b 100644 --- a/pokedex/db/load.py +++ b/pokedex/db/load.py @@ -4,7 +4,6 @@ import fnmatch import os.path import sys -from sqlalchemy.orm.attributes import instrumentation_registry import sqlalchemy.sql.util import sqlalchemy.types diff --git a/pokedex/db/markdown.py b/pokedex/db/markdown.py index 1ad304c..c9fd9a7 100644 --- a/pokedex/db/markdown.py +++ b/pokedex/db/markdown.py @@ -12,7 +12,7 @@ spline-pokedex. from __future__ import absolute_import import markdown -import sqlalchemy.types +import sqlalchemy class MarkdownString(object): """Wraps a Markdown string. Stringifies to the original text, but .as_html @@ -103,7 +103,7 @@ class MoveEffectPropertyMap(MoveEffectProperty): newdict[key] = _markdownify_effect_text(obj, newdict[key]) return newdict -class MarkdownColumn(sqlalchemy.types.TypeDecorator): +class MarkdownColumn(sqlalchemy.TypeDecorator): """Generic SQLAlchemy column type for Markdown text. Do NOT use this for move effects! They need to know what move they belong diff --git a/pokedex/db/multilang.py b/pokedex/db/multilang.py index 7e2840f..d027d13 100644 --- a/pokedex/db/multilang.py +++ b/pokedex/db/multilang.py @@ -5,8 +5,9 @@ from sqlalchemy.orm import aliased, compile_mappers, mapper, relationship, synon from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.orm.scoping import ScopedSession from sqlalchemy.orm.session import Session, object_session +from sqlalchemy.engine.base import Connection from sqlalchemy.schema import Column, ForeignKey, Table -from sqlalchemy.sql.expression import and_, bindparam, select +from sqlalchemy.sql.expression import and_, bindparam, select, Select from sqlalchemy.types import Integer def create_translation_table(_table_name, foreign_class, relation_name, @@ -167,20 +168,24 @@ class MultilangSession(Session): super(MultilangSession, self).__init__(*args, **kwargs) - def execute(self, clause, params=None, *args, **kwargs): - if not params: - params = {} - params.setdefault('_default_language_id', self.default_language_id) - - return super(MultilangSession, self).execute( - clause, params, *args, **kwargs) + def connection(self, *args, **kwargs): + """Monkeypatch the connection. Not pretty at all. + """ + conn = super(MultilangSession, self).connection(*args, **kwargs) + original_execute = conn.execute + if original_execute.__name__ != 'monkeypatched_execute': + def monkeypatched_execute(statement, *multiparams, **params): + if isinstance(statement, Select): + boundparams = dict(multiparams[0]) + boundparams.setdefault('_default_language_id', self.default_language_id) + multiparams = [boundparams] + list(multiparams[1:]) + return original_execute(statement, *multiparams, **params) + conn.execute = monkeypatched_execute + return conn class MultilangScopedSession(ScopedSession): """Dispatches language selection to the attached Session.""" - def __init__(self, *args, **kwargs): - super(MultilangScopedSession, self).__init__(*args, **kwargs) - @property def default_language_id(self): """Passes the new default language id through to the current session. diff --git a/setup.py b/setup.py index 3bc7028..2f5887e 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( 'pokedex': ['data/csv/*.csv'] }, install_requires=[ - 'SQLAlchemy>=0.6.6', + 'SQLAlchemy>=0.7.0b3', 'whoosh>=1.1.0', 'markdown', 'construct', -- 2.7.4