On Sep 25, 2009, at 4:11 PM, Andrew wrote:
> > So in a nut shell, its a function that uses the table operator to > generate an *actual* table, with five named columns. While this is > not great Oracle behavior, the PLSQL cannot be changed at this point > in time. Now, after discussing this with Michael, he suggested using > the compiler extension, so I came up with the following (basic) > construct: ok this is going to be awesome. to map to a selectable needs a few things in what you're selecting from - namely a column collection and a primary key. So we can instead map your serailized object to a TableClause subclass, where in addition to the serailized payload you'd give it information on what the column names and primary key cols would be. the mapper also wants things it selects from to have a name, so we just give it a name which is used as an oracle "alias name", i.e. "select foo.* from table(...) foo". Also I know you wanted to be able to change the thing being deserialized ad-hoc, so I've used the approach of an "alias()" of the "table" to provide that effect, which you can see below using the "using_source()" and orm "aliased" method to create ad-hoc mapped classes: from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.compiler import compiles from sqlalchemy.sql import expression class TableOper(expression.TableClause): def __init__(self, name, source, pk, *columns): super(TableOper, self).__init__(name, *columns) for name in pk: c = self.c[name] c.primary_key = True # for the mapper. less than ideal self.primary_key.add(c) self.source = source def using_source(self, source): return TableOper(self.name, source, [c.name for c in self.primary_key], *self.c) @compiles(TableOper) def compile_tableoper(element, compiler, **kw): return "table(%s) %s" % (element.source, element.name) device = TableOper('myname', 'some deserialization', ['id'], expression.column('id'), expression.column('x'), expression.column('y') ) class MyClass(object): pass mapper(MyClass, device) sess = sessionmaker()() print sess.query(MyClass).filter(MyClass.x==2) myclass_alias = aliased(MyClass, device.using_source('some other deserialization')) print sess.query(myclass_alias).filter(myclass_alias.x==2) The "myclass_alias" approach returns instances of MyClass as rows. I'm going to add this to the examples/ in 0.6 since the basic idea here can be used for a huge variety of situations (I just need to lookup the offical syntax for oracle table()). --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---