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.