Re: [sqlalchemy] orm mapper polymorphic_identity as collection

2011-07-29 Thread Michael Bayer

On Jul 28, 2011, at 7:05 PM, neurino wrote:

 I tried create_instance event and it fires, now having:
 
 def see_what_type(mapper, context, row, class_):
 if **is_air**:
 return Air()
 else:
 return EXT_CONTINUE
 
 def initialize_sql(engine):
 ...
 layer_mapper = mapper(Layer, layers)
 mapper(Air, inherits=layer_mapper)
 ...
 event.listen(Layer, 'create_instance', see_what_type,
   retval=True)
 
 and  setting **is_air** as True I get Air instances querying for Layer with 
 filled attributes and relationships.
 
 I don't know about other caveats...
 
 Now I have to find a robust way to check id_type (one of `row` items) in 
 see_what_type.

yeah thats one of the issues, those old extension interfaces were made before 
we had the aliased row in place which happens with the more elaborate 
subquery/join scenarios.

For the simple case you'd run in the Column object into the row:

row[mytable.c.type]

if you start dealing with subqueries and such, might have to make it look for a 
column that proxies the type column, which is entirely a workaround for the 
bad interface:

for key in row:
   if key.shares_lineage(mytable.c.type):
value = row[key]
break

but even that isn't going to work if you had two different Layer objects in the 
same result row.

Another workaround might be to establish the type of the mytable.c.type 
column using a TypeDecorator - where process_result_value() performs the rules 
you're looking for, returning is_air or not.   Then you'd use regular 
polymorphic_on.  Maybe give that a try ?


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



Re: [sqlalchemy] orm mapper polymorphic_identity as collection

2011-07-29 Thread neurino
Thanks Michael,

I was until now using a plain

row[u'layers_id_type']

found inspecting row.keys() with debugger (quick and ditry way, I know...)

now I changed with your more orthodox

row[mytable.c.id_type]

(ahem...)

I should not have to deal with subqueries so it can stay this way for the
time being.

I'm reading now for the first time in docs what's TypeDecorator for, and I
understand (approximately, please allow me some time to dive into it) your
suggestion.

My doubt, at the moment is: using Type Decorator will I be able to keep
using `mytable.c.id_type` as foreign key to types table (holding type name
adn so on) or not?

Probably reading docs better I'd get the answer by myself so don't mind...

I'll post results if I reach some good point.

Thanks again
neurino



On Fri, Jul 29, 2011 at 4:12 PM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Jul 28, 2011, at 7:05 PM, neurino wrote:

  I tried create_instance event and it fires, now having:
 
  def see_what_type(mapper, context, row, class_):
  if **is_air**:
  return Air()
  else:
  return EXT_CONTINUE
 
  def initialize_sql(engine):
  ...
  layer_mapper = mapper(Layer, layers)
  mapper(Air, inherits=layer_mapper)
  ...
  event.listen(Layer, 'create_instance', see_what_type,
retval=True)
 
  and  setting **is_air** as True I get Air instances querying for Layer
 with filled attributes and relationships.
 
  I don't know about other caveats...
 
  Now I have to find a robust way to check id_type (one of `row` items) in
 see_what_type.

 yeah thats one of the issues, those old extension interfaces were made
 before we had the aliased row in place which happens with the more
 elaborate subquery/join scenarios.

 For the simple case you'd run in the Column object into the row:

 row[mytable.c.type]

 if you start dealing with subqueries and such, might have to make it look
 for a column that proxies the type column, which is entirely a
 workaround for the bad interface:

 for key in row:
   if key.shares_lineage(mytable.c.type):
value = row[key]
break

 but even that isn't going to work if you had two different Layer objects in
 the same result row.

 Another workaround might be to establish the type of the mytable.c.type
 column using a TypeDecorator - where process_result_value() performs the
 rules you're looking for, returning is_air or not.   Then you'd use
 regular polymorphic_on.  Maybe give that a try ?


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



Re: [sqlalchemy] orm mapper polymorphic_identity as collection

2011-07-28 Thread Michael Bayer

On Jul 28, 2011, at 4:23 PM, neurino wrote:

 I need a Single Table Inheritance where the `type` column already
 exists and is a foreign key - `id_type` - to `types` table.
 
 My concern is I only need to map to two different classes:
 
 - Foo for `polymorphic_identity=FOO_ID_TYPE`
 - Bar for all other `id_type`s
 
 Is there a way I can accomplish this with two mappings?

we're working on easily allowing column_property() as a discriminator if you 
want to make a CASE statement.   right now its tedious as per the example at 
http://www.sqlalchemy.org/trac/ticket/2227 (note second example is single 
table, polymorphic_on needs to be on all subclasses at the moment)


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



Re: [sqlalchemy] orm mapper polymorphic_identity as collection

2011-07-28 Thread neurino
Thanks Michael,

my need is quite easy, no need of complex querying.

Simply my class represents a Layer and, while quite all layer types
(concrete, wood, bricks, etc.) act the same, only one (air) acts in a
completely different way.

With act I refer to performing calculations on float attributes, no more.

So I can simply put in all calc functions separate operations:

if self.type == air:
#air calcs
else:
#all others calcs

or, in a more elegant way, use a Layer subclass named Air.

I can't create subclasses for all other layers since I don't know them in
advance.

As far as I understand I have to go with first solution at the moment,
right?



On Thu, Jul 28, 2011 at 11:38 PM, Michael Bayer mike...@zzzcomputing.comwrote:

 column_property()

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



Re: [sqlalchemy] orm mapper polymorphic_identity as collection

2011-07-28 Thread Michael Bayer

On Jul 28, 2011, at 6:08 PM, neurino wrote:

 Thanks Michael,
 
 my need is quite easy, no need of complex querying.
 
 Simply my class represents a Layer and, while quite all layer types 
 (concrete, wood, bricks, etc.) act the same, only one (air) acts in a 
 completely different way.
 
 With act I refer to performing calculations on float attributes, no more.
 
 So I can simply put in all calc functions separate operations:
 
 if self.type == air:
 #air calcs
 else:
 #all others calcs
 
 or, in a more elegant way, use a Layer subclass named Air.
 
 I can't create subclasses for all other layers since I don't know them in 
 advance.
 
 As far as I understand I have to go with first solution at the moment, right?

probably, there's an old event for this called create_instance (1) that was 
meant for this a long time ago but I don't know what kinds of caveats it has 
with modern usage.   polymorphic_on=callable is ticket #1131 (2), note it is 
very old and the code examples there are out of date.


1: 
http://www.sqlalchemy.org/docs/orm/events.html#sqlalchemy.orm.events.MapperEvents.create_instance
2: http://www.sqlalchemy.org/trac/ticket/1131

 
 
 
 On Thu, Jul 28, 2011 at 11:38 PM, Michael Bayer mike...@zzzcomputing.com 
 wrote:
 column_property()
 
 
 -- 
 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.



Re: [sqlalchemy] orm mapper polymorphic_identity as collection

2011-07-28 Thread neurino
I tried create_instance event and it fires, now having:

def see_what_type(mapper, context, row, class_):
if **is_air**:
return Air()
else:
return EXT_CONTINUE

def initialize_sql(engine):
...
layer_mapper = mapper(Layer, layers)
mapper(Air, inherits=layer_mapper)
...
event.listen(Layer, 'create_instance', see_what_type,
  retval=True)

and  setting **is_air** as True I get Air instances querying for Layer with
filled attributes and relationships.

I don't know about other caveats...

Now I have to find a robust way to check id_type (one of `row` items) in
see_what_type.

Any advice?

Thanks for your support


On Fri, Jul 29, 2011 at 12:15 AM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Jul 28, 2011, at 6:08 PM, neurino wrote:

 Thanks Michael,

 my need is quite easy, no need of complex querying.

 Simply my class represents a Layer and, while quite all layer types
 (concrete, wood, bricks, etc.) act the same, only one (air) acts in a
 completely different way.

 With act I refer to performing calculations on float attributes, no more.

 So I can simply put in all calc functions separate operations:

 if self.type == air:
 #air calcs
 else:
 #all others calcs

 or, in a more elegant way, use a Layer subclass named Air.

 I can't create subclasses for all other layers since I don't know them in
 advance.

 As far as I understand I have to go with first solution at the moment,
 right?


 probably, there's an old event for this called create_instance (1) that was
 meant for this a long time ago but I don't know what kinds of caveats it has
 with modern usage.   polymorphic_on=callable is ticket #1131 (2), note it is
 very old and the code examples there are out of date.


 1:
 http://www.sqlalchemy.org/docs/orm/events.html#sqlalchemy.orm.events.MapperEvents.create_instance
 2: http://www.sqlalchemy.org/trac/ticket/1131




 On Thu, Jul 28, 2011 at 11:38 PM, Michael Bayer 
 mike...@zzzcomputing.comwrote:

 column_property()



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


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