Maybe I did something wrong so loosely following the example
http://techspot.zzzeek.org/?p=4
which I realize is a bit old now. I was able to get my basic mappers
setup and working.
class NodeLoader(MapperExtension):
def create_instance(self, mapper, selectcontext, row, class_):
#print row
if row['nodehierarchy_type'] == 'file':
return FileNode(None,None,None)
else:
return Node(None,None,None)
However the index in the RowProxy changes if I try to eagerload the
children. So this works:
a=query =
session.query(Node).filter(Node.name=='testytest').filter(Node.parentuid==uid).first()
But this fails:
a=query =
session.query(Node).filter(Node.name=='testytest').filter(Node.parentuid==uid).options(eagerload_all('Children')).first()
I get:
File
"/users/dgardner/dev/lib/python2.5/site-packages/SQLAlchemy-0.5.0rc2-py2.5.egg/sqlalchemy/engine/base.py",
line 1508, in lookup_key
raise exc.NoSuchColumnError("Could not locate column in row for
column '%s'" % (str(key)))
sqlalchemy.exc.NoSuchColumnError: "Could not locate column in row for
column 'nodehierarchy_type'"
Is there a better way to do this? I still have the option of reverting
to my original mapper setup where I mapped the classes against select()
queries.
David Gardner wrote:
> Aha! This worked perfectly. I followed your create_instance() example at
> http://techspot.zzzeek.org/?p=4
>
> I definitely owe you a beer!
>
> Michael Bayer wrote:
>
>> On Oct 30, 2008, at 5:30 PM, David Gardner wrote:
>>
>>
>>
>>> This works. However although type=='file' is the only time I want/need
>>> to have a subclass for, I still need to know the original value of
>>> type.
>>> Is there a way in SA to basically get two copies of the column?
>>> Maybe I
>>> could return a tuple from MyRow.__getitem__ ?
>>>
>>> The best think I can think of is to create a view (PostgreSQL):
>>> CREATE OR REPLACE VIEW nodehierarchy_view AS SELECT *, type AS poly
>>> FROM nodehierarchy;
>>>
>>> and map my classes against the view, that way I have two copies of the
>>> type columns.
>>>
>>> To complicate things slightly more I am joining against a type table,
>>> who's primary key is a text field. So typically when I just want to
>>> know
>>> the name of the type I do node.type, but sometimes I need additional
>>> information and do a node.Type.other_info. Right now the relation is
>>> commented out since it isn't working.
>>>
>>> node_mapper = mapper(Node, nodehierarchy_table, extension=MyExt(),
>>> polymorphic_on=nodehierarchy_table.c.type,
>>> polymorphic_identity='node',
>>> properties = {
>>> #'Type' : relation (Type,
>>> primaryjoin=(type_table.c.name==nodehierarchy_table.c.type),
>>> uselist=False),
>>>
>>>
>> The way I'd want to add "polymorphic_on as a callable" would allow one
>> to replace the entire mechanism of the "discriminator", such that
>> there's not even a specific column that SQLA knows about in that
>> regard. This is a moderate change to the mapper internals, but the
>> big behavioral change is that the *population* of the column would
>> also become something you'd have to do on your end, and I'd also have
>> to figure out what its behavior with regards to querying becomes - it
>> would probably be several functions the user needs to implement.
>>
>> Right now Im wondering if it's not easier for you to just provide a
>> create_instance() mapper extension that just returns the base class
>> for all discriminators other than "file", and you just do away with
>> using polymorphic_on. The fact that you are compressing all those
>> discriminators into one class means that you're losing a lot of the
>> semantics of inheritance already- you cant query for them without
>> explicitly saying filter(discriminator==sometype), for example.
>>
>>
>>
>
>
> --
> David Gardner
> Pipeline Tools Programmer, "Sid the Science Kid"
> Jim Henson Creature Shop
> (323) 802-1717 [EMAIL PROTECTED]
>
>
>
> >
>
>
--
David Gardner
Pipeline Tools Programmer, "Sid the Science Kid"
Jim Henson Creature Shop
(323) 802-1717 [EMAIL PROTECTED]
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---