consider rollup of __clause_element__() onto ClauseElement

Issue #3816 new
Mike Bayer repo owner created an issue

tried to do this for #3802 late in 1.1 but it's too critical if someone is doing a while loop, and here's at least one example: https://github.com/albertov/py-mailing/blob/a81d71f35b3c04de75cca48eb82b0b85bbaaf915/mailing/models/util.py#L45. there's no reason that person would have done that besides copying our code. additionally, if we put __clause_element__() onto ClauseElement, there's a lot of internal checks that should also be optimized.

other more far-out tricks would be:

  1. return a copy of the object that raises some assertion on __clause_element__(). though this is expensive

  2. deprecate __clause_element__() and replace with some totally other method. But we'd need almost-forever backwards compat for calling upon __clause_element__ also in this case. It sort of suggests all the places where we do hasattr(obj, '__clause_element__') should become some other kind of single call that perhaps we can put into cutils. Detecting __clause_element__ itself would then raise some kind of deprecation warning.

Comments (7)

  1. Mike Bayer reporter

    e.g. like this:

    diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py
    index 768574c..99d214c 100644
    --- a/lib/sqlalchemy/sql/elements.py
    +++ b/lib/sqlalchemy/sql/elements.py
    @@ -4218,11 +4218,11 @@ def _expression_literal_as_text(element):
    
    
     def _literal_as_text(element, warn=False):
    -    if isinstance(element, Visitable):
    -        return element
    -    elif hasattr(element, '__clause_element__'):
    -        return element.__clause_element__()
    -    elif isinstance(element, util.string_types):
    +    clauseelement = util.reduce_clauseelement(element)
    +    if clauseelement is not None:
    +        return clauseelement
    +
    +    if isinstance(element, util.string_types):
             if warn:
                 util.warn_limited(
                     "Textual SQL expression %(expr)r should be "
    
  2. Mike Bayer reporter

    __sql_expr__

    __sqla_expr__

    as_sqlalchemy

    __expression__

    __sql_expression__

    as_sql_element

    as_clauseelement

  3. Mike Bayer reporter

    maybe it's time to rename ClauseElement to SQLElement anyway. ClauseElement has always been awkward.

  4. Mike Bayer reporter
    • changed milestone to 1.3

    it's not clear how much benefit this is besides correctness, pushing this out for now

  5. Log in to comment