str() call in make_proxy can get in the way w/ dialect specific operators

Issue #2780 resolved
Mike Bayer repo owner created an issue
when I use .order_by(SmtObject.array_field[3](3)) without .limit(50) or limit(any_num) without order(array_field[index](index)) dialect is
sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at.... sometimes.

But using .order_by(SmtObject.array_field[3](3)).limit(50) both direct to exception:

File "/Users/aterentev/lamoda/apilib/develop.py", line 37, in
for p in session.query(Product).filter(Product.id > 100000).order_by(Product.sortings[3](3)).limit(60):
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2212, in iter
context = self._compile_context()
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2561, in compile_context
context.statement = self._compound_eager_statement(context)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2618, in _compound_eager_statement
eager_join, eager_join.stop_on)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/util.py", line 608, in splice_joins
right.onclause = adapter.traverse(right.onclause)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py", line 197, in traverse
return replacement_traverse(obj, self._traverse_options__, replace)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py", line 305, in replacement_traverse
obj = clone(obj, **opts)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py", line 294, in clone
newelem = replace(elem)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py", line 194, in replace
e = v.replace(elem)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/util.py", line 843, in replace
return self._corresponding_column(col, True)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/util.py", line 820, in corresponding_column
require_embedded=require_embedded)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 2730, in corresponding_column
if self.c.contains_column(column):
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 614, in __get_
obj.__dict__[self.__name__](self.__name__) = result = self.fget(obj)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 2804, in columns
self._populate_column_collection()
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 4079, in populate_column_collection
for col in self.element.columns:
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 614, in __get_
obj.__dict__[self.__name__](self.__name__) = result = self.fget(obj)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 2804, in columns
self._populate_column_collection()
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 5846, in populate_column_collection
name_is_truncatable=True)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 2350, in _make_proxy
key = str(self)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 1920, in __str_
return unicode(self.compile()).encode('ascii', 'backslashreplace')
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 1908, in compile
return self._compiler(dialect, bind=bind, **kw)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 1914, in compiler
return dialect.statement_compiler(dialect, self, **kw)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py", line 289, in __init_
engine.Compiled.__init__(self, dialect, statement, **kwargs)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/engine/interfaces.py", line 787, in init
self.string = self.process(self.statement, **compile_kwargs)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/engine/interfaces.py", line 806, in process
return obj._compiler_dispatch(self, **kwargs)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py", line 74, in _compiler_dispatch
return getter(visitor)(self, **kw)
File "/Users/aterentev/lamoda/apipy/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py", line 660, in visit_binary
OPERATORS[operator](operator), **kw)
KeyError: <built-in function getitem>

Comments (4)

  1. Mike Bayer reporter

    My guess as to how the original poster only uses the index operator in order_by and still sees this is because the eager load is trying to stick that column in the columns clause so that it can order the enclosing query the same way. so for our purposes the bug is just this:

    from sqlalchemy.dialects.postgresql import ARRAY
    
    from sqlalchemy import Integer
    from sqlalchemy.sql import table, column, select
    
    t = table('t', column('x', ARRAY(Integer)))
    
    s = select([t.c.x[5](t,)])
    
    s.corresponding_column(t.c.x)
    
  2. Log in to comment