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 sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to