[sqlalchemy] Re: Polymorphic and inheritance with missing children

2008-02-07 Thread Michael Bayer


On Feb 7, 2008, at 1:33 PM, Richard Levasseur wrote:

 For the syntax of it, I'd go for something like
 `child_obj.change_from(parent_obj)` or `child_obj =
 ChildClass.create_from(parent_obj)`, perhaps implicitly invoked when
 you do child_obj.type = parent_obj.  Not sure about that last part,
 doesn't seem pythonic, and feels misleading.  The point is to allow
 the child the ability to perform custom operations if need be
 (__change_type__?).  Is the `session` part really necessary (I thought
 objects knew what session, if any, they were attached to?).  I don't
 recall exactly if this is possible, but perhaps the child can have its
 __dict__ set to the parent's?  That'd preserve any state and wouldn't
 require any loop-copy of attributes.

the session part is introduced only in that we try not to attach  
lots of methods and accessors to user-defined classes. we like to  
leave user-defined classes as unmodified as possible which at the very  
least helps with the possibility of name collisions (like, if someones  
SA app has a change_from method already, this change would break  
their app).   since everything else comes from session (like  
expunge(), refresh(), etc) this is where we like to put these things  
for consistency.

however, thinking further about this I think how we'd actually do this  
would be the same way we do a primary key switch - the mapper  
already knows how to detect the delete of one instance and the  
insert of another, both with the same primary key attributes, and  
turn it into an update.  So i would see this as an extension to that  
functionality, i.e.:

parent = sess.query(Parent).get(1)
child = Child(id=1)
child.someattr = parent.someattr  # copy attributes
sess.delete(parent)
sess.save(child)
sess.flush()





--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic and inheritance with missing children

2008-02-07 Thread Richard Levasseur

On Feb 6, 7:01 pm, Michael Bayer [EMAIL PROTECTED] wrote:
 we dont yet support a seamless change of inheriting type.  your best
 bet is to issue the SQL to the table directly which changes the
 polymorphic value to the new value, then inserting/deleting from the
 child tables as needed..then reload the object into your session (i.e.
 expunge() the old one first).

Ok, I guess I'll play around with that at work a bit.


 the reason its not yet supported is because the extra steps of
 INSERTing and/or DELETEing in conjunction with what would normally
 just be an UPDATE are a little complex...also we'd have to pick an API
 for this (like, myobject = session.change_type(myobject, FooClass) ?
 not sure).  but we'll get this in there sooner or later (sooner if its
 an urgent need for people).

In our instance, its fairly important, we have about 30 different
types, half of which have child tables, the other half are within the
same parent table.  I still need to figure out how to load the child
when its record is missing, too.

For the syntax of it, I'd go for something like
`child_obj.change_from(parent_obj)` or `child_obj =
ChildClass.create_from(parent_obj)`, perhaps implicitly invoked when
you do child_obj.type = parent_obj.  Not sure about that last part,
doesn't seem pythonic, and feels misleading.  The point is to allow
the child the ability to perform custom operations if need be
(__change_type__?).  Is the `session` part really necessary (I thought
objects knew what session, if any, they were attached to?).  I don't
recall exactly if this is possible, but perhaps the child can have its
__dict__ set to the parent's?  That'd preserve any state and wouldn't
require any loop-copy of attributes.
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Elixir 0.5.1 released!

2008-02-07 Thread Gaetan de Menten

I am very pleased to announce that version 0.5.1 of Elixir
(http://elixir.ematia.de) is now available. As always, feedback is
very welcome, preferably on Elixir mailing list.

This is mostly a bug fixes release (especially for people using
inheritance), but we have also a few minor new features, including a
new plugin for managing entities as (ordered) lists, enhanced support
for custom base classes and an alternate (nicer) syntax to define
synonym properties.

The full list of changes can be seen at:
http://elixir.ematia.de/trac/browser/elixir/tags/0.5.1/CHANGES

What is Elixir?
-

Elixir is a declarative layer on top of the SQLAlchemy library. It is
a fairly thin wrapper, which provides the ability to create simple
Python classes that map directly to relational database tables (this
pattern is often referred to as the Active Record design pattern),
providing many of the benefits of traditional databases without losing
the convenience of Python objects.

Elixir is intended to replace the ActiveMapper SQLAlchemy extension,
and the TurboEntity project but does not intend to replace
SQLAlchemy's core features, and instead focuses on providing a simpler
syntax for defining model objects when you do not need the full
expressiveness of SQLAlchemy's manual mapper definitions.

Mailing list


http://groups.google.com/group/sqlelixir/about

-- 
Gaƫtan de Menten
http://openhex.org

--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] self referential query with order_by

2008-02-07 Thread David Gardner

I have a self referential hierarchy structure in a table that I have 
mapped with SA 0.4. What I would like to do is query the table given a 
node, and find its grandchildren based on some criteria in both the 
child and grandchildren nodes. In SQL I would do:

SELECT * FROM nodehierarchy AS grandparent
JOIN nodehierarchy AS parent ON parent.parentuid = grandparent.uid
JOIN nodehierarchy AS child ON child.parentuid = parent.uid
WHERE grandparent.uid = some_value
AND parent.type=different_value
AND child.type=another_value
ORDER BY parent.name, child.name;


Following the third example from 
http://www.sqlalchemy.org/docs/04/mappers.html#advdatamapping_relation_selfreferential_query
I have the following:

grandchildren = session.query(Node).filter(Node.c.type==var1).\
join('Parent', aliased=True).filter(Node.c.type==var2).\
join('Parent',aliased=True, 
from_joinpoint=True).filter(Node.uid==var3).all () # 
order_by(Node.Parent.name, Node.name).all()

grandchildren.sort (key=lambda i: (i.Parent.name,i.name))

However the commented out order_by() doesn't work I get AttributeError: 
'InstrumentedAttribute' object has no attribute 'name'
As you can see I am currently sorting client side.


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Polymorphic and inheritance with missing children

2008-02-07 Thread Richard Levasseur

Ok, so I've been looking into getting it to work when the child record
doesn't exist.  I haven't had much luck.

I wrote a stub mapper extension for translate_row and
populate_instance, but it doesn't seem to be called when it goes to
fetch the information for the child row.
mapper(Parent, parents, polymorphic.)
mapper(Child, children, extension=MyExtension(def translate_row, def
populate_instance))

query(Parent)
my translate_row called
my populate_instance called
mapper.py:_get_poly_select_loader, the first inline post_execute is
called to fetch the data:
  row = selectcontext.session.connection(self).execute(statement,
params).fetchone()
  self.populate_instance(selectcontext, instance, row, isnew=False,
instancekey=identitykey, ispostselect=True)

Shouldn't translate_row be called before then?  In the working case
(child exists), neither of my extension methods are called, too.  It
makes sense that they would only be called once per result, but in
this case a single result is actually 2 records fetch separately.
--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---