On Feb 7, 2011, at 11:16 AM, Kent wrote:

> On Feb 4, 12:04 pm, Kent <jkentbo...@gmail.com> wrote:
>> Excellent, it is working for the simpler case, but for oracle 8 (who
>> isn't as smart when indexing) I also need it to work for
>> subqueryload().
>> 
>> So the problem is that my FOR UPDATE OF is also being added for
>> subqueryload selects.
>> 
>> * Can I tell within the compiles context if this is for subqueryload?
>> (Or can the Query tell?)
> 
> 
> What I worked out based on compiler.is_subquery() is that
> compiler.stack (in other words, bool(compiler.stack)) should tell me
> if this is a subqueryload.  Does that sound accurate?

yes that is actually the appropriate way to detect if the current context is 
that of a subquery.   (is_subquery() that is.   I'd prefer that over peeking 
into the stack itself).




> 
> 
>> 
>> * Are there other cases where the query is "reused" that I need to be
>> careful of?
>> 
>> I restructured this way (as you're original suggestion to fix another
>> issue):
>> 
>> @compiles(Select)
>> def compile_forupdateof(select, compiler, **kw):
>>     rendered = compiler.visit_select(select, **kw)
>>     if hasattr(select, '_for_update_of'):
>>         mapper = class_mapper(select._for_update_of)
>>         name = mapper.mapped_table.name
>>         if compiler.dialect.name == 'oracle':
>>             # Oracle makes us specify the column name (for views, I
>> guess, since it locks entire row)
>>             name += '.' + mapper.primary_key[0].name
>>         rendered = "%s FOR UPDATE OF %s" % (rendered, name)
>>     return rendered
>> 
>> On Feb 3, 9:51 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
>> 
>>> On Feb 3, 2011, at 9:29 PM, Kent wrote:
>> 
>>>> Yeah, I wanted to apologize because my heart wants to contribute to
>>>> the project (really), but I'm working overtime like mad swamped
>>>> because our product is live in use now and I've got a backload of
>>>> tickets to solve!  I also feel my level of understanding currently is
>>>> more hacking than contributing.  I hope to be of more help to the
>>>> project in the future.
>> 
>>>> Is "simpler than you had in mind" a good thing or am I over
>>>> simplifying and it won't work for bunch of cases?
>> 
>>>> I note that the simple case is working, but something like this fails:
>> 
>>>> DBSession.query(Order).for_update_of(Order).limit(10).all()
>> 
>>>> since I really need to have the for update inside in this case... any
>>>> advise or is this what you meant by "There's not a great way to
>>>> intercept the middle of the SELECT compilation with a new kind of
>>>> clause in this case."?
>> 
>>> i think if it works for what you need right now, then its great.   
>>> @compiles is meant to give you what you need to get out of a jam.
>> 
>>>> On Feb 3, 9:07 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
>>>>> oh OK this is a little simpler than what I had in mind, you just have to 
>>>>> add the mixin expression.Executable to your ForUpdateOf class.
>> 
>>>>> On Feb 3, 2011, at 9:05 PM, Kent wrote:
>> 
>>>>>> Here is a crude outline (need to properly escape table name, etc.), of
>>>>>> what I think might work, and it seems to render properly, but crashes
>>>>>> with:
>> 
>>>>>>  File "/home/rarch/tg2env/lib/python2.6/site-packages/
>>>>>> SQLAlchemy-0.6.4.2kbdev-py2.6-linux-x86_64.egg/sqlalchemy/engine/
>>>>>> default.py", line 353, in __init__
>>>>>>    raise exc.ArgumentError("Not an executable clause: %s" % compiled)
>>>>>> ArgumentError: Not an executable clause:
>>>>>> ...
>> 
>>>>>> class MyQuery(Query):
>>>>>>    _for_update_of = None
>> 
>>>>>>    @_generative()
>>>>>>    def for_update_of(self, arg):
>>>>>>        """Keep track that we want to for update of this"""
>>>>>>        self._for_update_of = class_mapper(arg).mapped_table.name
>> 
>>>>>>    def _compile_context(self, labels=True):
>>>>>>        context = super(MyQuery, self)._compile_context(labels)
>>>>>>        if self._for_update_of:
>>>>>>            context.statement = ForUpdateOf(context.statement,
>>>>>> self._for_update_of)
>>>>>>        return context
>> 
>>>>>> class ForUpdateOf(ClauseElement):
>>>>>>    def __init__(self, statement, for_update_of):
>>>>>>        self.statement = statement
>>>>>>        self.for_update_of = for_update_of
>> 
>>>>>> @compiles(ForUpdateOf)
>>>>>> def compile_forupdateof(element, compiler, **kw):
>>>>>>    return "%s FOR UPDATE OF %s" %
>>>>>> (compiler.process(element.statement), element.for_update_of)
>> 
>>>>>> --
>>>>>> You received this message because you are subscribed to the Google 
>>>>>> Groups "sqlalchemy" group.
>>>>>> To post to this group, send email to sqlalchemy@googlegroups.com.
>>>>>> To unsubscribe from this group, send email to 
>>>>>> sqlalchemy+unsubscr...@googlegroups.com.
>>>>>> For more options, visit this group 
>>>>>> athttp://groups.google.com/group/sqlalchemy?hl=en.
>> 
>>>> --
>>>> You received this message because you are subscribed to the Google Groups 
>>>> "sqlalchemy" group.
>>>> To post to this group, send email to sqlalchemy@googlegroups.com.
>>>> To unsubscribe from this group, send email to 
>>>> sqlalchemy+unsubscr...@googlegroups.com.
>>>> For more options, visit this group 
>>>> athttp://groups.google.com/group/sqlalchemy?hl=en.
>> 
>> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to