I have a little code using sqlalchemy.ext.compiler'
from sqlalchemy import Table, Column
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import HasPrefixes
from sqlalchemy.sql.expression import Executable
from sqlalchemy.sql.expression import ClauseElement
#
# EXPLAIN
#
class Explain(HasPrefixes, Executable, ClauseElement):
_prefixes = ()
def __init__(self, stmt, prefixes=None):
self.stmt = stmt
if prefixes:
self._setup_prefixes(prefixes)
@compiles(Explain)
def visit_explain(explain, compiler, **kw):
text = "EXPLAIN "
if explain._prefixes:
text += compiler._generate_prefixes(explain, explain._prefixes,
**kw)
text += compiler.process(explain.stmt)
# Can't remember why I needed these >:O
compiler.isinsert = False
compiler.isupdate = False
compiler.isdelete = False
return text
def explain(stmt, **kw):
return Explain(stmt, **kw)
from sqlalchemy import MetaData, String, create_engine
metadata = MetaData()
table = Table('t', metadata, Column('c', String))
engine = create_engine('sqlite://')
table.create(engine)
update = table.update().values(c='something')
print [dict(r) for r in engine.execute(explain(update, prefixes=['QUERY
PLAN']))]
This runs ok under 0.9.1, but if I upgrade to 0.9.3 I get a traceback
complaining about no '_extra_froms'.
(wexdev)gsbrown@gsbrowndesktop:~/Sandbox/sa_explain$ python explain.py
Traceback (most recent call last):
File "explain.py", line 44, in <module>
print [dict(r) for r in engine.execute(explain(update, prefixes=['QUERY
PLAN']))]
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py",
line 1651, in execute
return connection.execute(statement, *multiparams, **params)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py",
line 717, in execute
return meth(self, multiparams, params)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/elements.py",
line 317, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/engine/base.py",
line 807, in _execute_clauseelement
inline=len(distilled_params) > 1)
File "<string>", line 1, in <lambda>
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/elements.py",
line 468, in compile
return self._compiler(dialect, bind=bind, **kw)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/elements.py",
line 474, in _compiler
return dialect.statement_compiler(dialect, self, **kw)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py",
line 391, in __init__
Compiled.__init__(self, dialect, statement, **kwargs)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py",
line 197, in __init__
self.string = self.process(self.statement, **compile_kwargs)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py",
line 220, in process
return obj._compiler_dispatch(self, **kwargs)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/ext/compiler.py",
line 410, in <lambda>
lambda *arg, **kw: existing(*arg, **kw))
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/ext/compiler.py",
line 448, in __call__
return fn(element, compiler, **kw)
File "explain.py", line 26, in visit_explain
text += compiler.process(explain.stmt)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py",
line 220, in process
return obj._compiler_dispatch(self, **kwargs)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/visitors.py",
line 79, in _compiler_dispatch
return meth(self, **kw)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py",
line 1778, in visit_update
colparams = self._get_colparams(update_stmt, **kw)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py",
line 1913, in _get_colparams
self._key_getters_for_crud_column
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/util/langhelpers.py",
line 689, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File
"/home/gsbrown/Envs/wexdev/local/lib/python2.7/site-packages/SQLAlchemy-0.9.3-py2.7-linux-x86_64.egg/sqlalchemy/sql/compiler.py",
line 1849, in _key_getters_for_crud_column
if self.isupdate and self.statement._extra_froms:
AttributeError: 'Explain' object has no attribute '_extra_froms'
I can fix this by making the Explain statement have an '_extra_froms'
attribute, but I'm not sure if that should just be empty or borrowed from
the wrapped statement or what. Any suggestions on how best to keep this
clean?
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.