hi gang -

seems like I am getting a grip on whats really going to be different  
and such in 0.4.  I think it would be a good idea for me to put out  
there some of the things i want to remove, as well as a few notable  
backwards-incompatible changes, just to give a heads up.  Note that  
this list is only things that youll *have* to do in order to use  
0.4...im not including things that are deprecated but will still work  
throughout 0.4.

1. import structure

The biggest thing, and im not sure if people are ready for this one,  
is separating "sqlalchemy" from "sqlalchemy.orm".  Its been the case  
for a long time that you can do your imports like this:

from sqlalchemy import *
from sqlalchemy.orm import *

and obviously you can import the specific classes explicitly, i.e.

from sqlalchemy import Table, Column
from sqlalchemy.orm import mapper, relation, backref

in 0.4, "sqlalchemy" is no longer going to pull in the whole list of  
"sqlalchemy.orm" into its namespace.  this means, to use mappers, you  
*have* to import from the "sqlalchemy.orm" package explicitly as  
above.  this is partially to raise awareness of the fact that there  
is a pretty strict separation between the two packages, and to  
encourage better organization of concerns.  so that means if you use  
mapper(), relation(), backref(), create_session(), eagerload()/ 
lazyload(), you have to import them from sqlalchemy.orm.  this  
upcoming change has been mentioned on the tutorial page for several  
months now too.

what the frameworks and such can do *right now*, is to start  
importing as appropriate from 'sqlalchemy.orm' for object-relational  
functionality.  that way this wont present an issue with an 0.4 upgrade.

like i mentioned, if theres really some severe issue with this, we  
can perhaps come up with a hack to "backfill" 'sqlalchemy.orm' into  
'sqlalchemy' for some software package that cant be updated, but i  
really want to try to get just this one little cleanup of concerns  
out there.

2. assignmapper query methods

The next  biggest thing is assignmapper.  OK, im not taking  
assignmapper away.  But I am going to change the interface.  All  
querying will be available off of a single attribute, "query".  most  
likely the parenthesis (i.e. class.query()) will not be needed.  so:

MyClass.query.filter_by(street='123 green street').all()

this is because we cant just keep putting every single method from  
Query on the mapped class.  plus with Query being generative, it  
makes even less sense for any of the methods to be off of the class  
directly.   id like to just take all the other select(), select_by()  
methods off of it, because i really want people to stop using them.   
you can start using MyClass.query() right now, which will still work  
with the parens in 0.4, and in 0.3.9 ill try to get  
MyClass.query.<foo> to work as well so you can be totally forwards  
compatible with 0.3.9.

3. assignmapper myobject.flush()

this is the other thing I really want to get rid of on assignmapper.   
this is the most overused and anti-patternish thing out there.  it  
doesnt predictably handle the things attached to it (which is not for  
any strong technical reason, just that its a complicated case which  
id rather not have to bother with), and it works against the kinds of  
patterns the Session is intended to be used for.  you still can flush  
an individual or group of instances, which is valid in certain cases,  
by calling session.flush([<objects>])...but that ensures that you  
really mean to do that.

4. global_connect() / default_metadata

as well as the ability to say "Table('sometable', Column(...)...)"  
etc without using any MetaData.  This one i know is going to raise  
some ire.  But I look at it this way:  someday, Guido is going to  
take a look at SQLAlchemy, and when that day comes, i dont want there  
to be a trace that this ugly thing ever existed...it screams "SA cant  
decide how its API should look".  Plus it used DynamicMetaData which  
is a totally misunderstood object that isnt going away but will be  
much more downplayed.  youre responsible for your own MetaData object  
and telling your Table objects about it.

5. clear_mapper()

note this is *not* clear_mappers(), which is a pretty important  
function.  this one, the ability to clear just *one* mapper, is going  
away..because this capability never really existed anyway.  the total  
set of mappers for your application organize themselves into their  
own symbiotic ecosystem....splicing just one from out of it is a  
configurational game of jenga you'll never win.  i dont think this  
was a very commonly used function.


Taking more of a stroll down memory lane, see if you remember these  
tunes:

6. cascade_mappers()

If you've been around long enough to know what this one does, I  
commend you.  but if you've then not been paying attention enough to  
know that i hate this function, shame on you !  this thing just  
sucks.  folks are free to copy it into their own library of mediocre  
functions if they actually use it for something.

7. query.select_by_whatever('something')

yeah, back when we thought ActiveRecord was cool.  or at least  
someone told me it was.  anyway, i dont think this one is too common.

8. table.select().execute(col1=5, col2=7) == "SELECT * FROM TABLE  
WHERE col1=5 AND col2=7".

I am fairly certain that nobody knows what i am talking about here  
since this one was never documented.  If you think its cool, too bad  
you missed the past 2 years to enjoy this doomed trick.

9. ProxyEngine

This is a feature that I *like*, its just that it hasnt worked for  
about 18 months.  The ProxyEngine *will* be back at some later date,  
in a new form, but for now its offline.

10. SelectResults (sort of)

if youre using SelectResults, it will still import and act *mostly*  
the same as it used to...but its just a placeholder now that does  
almost nothing, since the Query has all of its functionality.  so the  
behavior of join() changes slightly (see #13 below).

11. everything in sqlalchemy.mods

I just realized theres nothing in here we should be keeping.  This  
would include "sqlalchemy.mods.threadlocal", which is evil, and the  
never used "legacy_session" and "selectresults" mods.  selectresults  
mod is particularly unneeded becuase like in 10, all of SelectResults  
is on Query now.

Next up are some things that are not going away but are going to  
change backwards-incompatibly:

12. select.order_by() and select.group_by() (i.e. on the SQL select()  
construct) are going to be generative, i.e. they return a new select  
object.  the old behavior will be present in select.append_order_by()  
and select.append_group_by()   (yes, I decided to keep both  
generative and in-place APIs for this.  but we're going to push the  
generative API and leave the "append_" versions just in docstrings).

13. also slightly backwards incompatible:  session.query(A).join 
('b').join('c') in 0.3 produces "select * from a join b on a.id=b.id  
join c on b.id=c.id".  in 0.4, both 'b' and 'c' will be interpreted  
as attributes on 'A', as in "select * from a join b on a.id=b.id join  
c on a.id=c.id".  to get a join from A->b->c, do session.query(A).join 
(['b', 'c']).  this new way allows you to re-join from the root as  
often as you like.  if you need totally custom joins, use  
query.select_from(<custom join objects>).  there is also a cool  
"aliased" version of joins you can do in query.filter_by().

14.  on the subject of filter_by(), filter_by(*clauseelements,  
**kwargs) becomes just filter_by(**kwargs).   you put the Table/ 
Column expressions in a filter() call.  the deprecated select_by()/ 
count_by()/etc. will still be there and will allow the old style.

15. custom dictionary collections are now much more powerful at the  
expense of being slightly more finicky (i.e.  
collection_class=MyDict).  quickest way to make your custom  
dictionary class compatible is to either subclass dict, or add the  
mixin class sqlalchemy.orm.collections.MappedCollection (i.e. class  
MyDict(MappedCollection):).  the __iter__() method goes back to  
normal (returns keys) and you also need to implement a remove()  
method.  We'll see if we can produce a forwards compatible emulation  
of this in 0.3.9.

...and there you have it, all I can think of for now.



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

Reply via email to