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
-~----------~----~----~----~------~----~------~--~---

Reply via email to