Q: How to make sqlalchemy session keep track of all changes in the locally created objects? Sqlalchemy keeps track of all the changes and commit to the database if I do this:
b =  this_session.query(BaseUrl).filter_by(id=value).first()
b.basevalue = "new_value" #changing 
this_session.commit()     #commit the change to the DB

That works great.
However, if I use this:
proxy =  this_session.execute("select * from base_url where id = {0}".format(value))
b = create_base_url(proxy) #create an instance of BaseUrl from proxy!
b.basevalue = "new_value"  #changing 
this_session.commit()      #it does NOT commit the change to the DB

Of course, the problem with create_base_url().  In this function, I'm simply creating an instance of BaseUrl by passing various arguments taken from the proxy and return it. I don't do anything else in order to make this_session to keep track of all the changes in the object. I need a functionality something like this:
this_session.attach(b) #keep track of changes in b

so as to keep track of all changes in b.
How should I implement such a functionality? It would be also good if I have the opposite:
this_session.detach(b) #don't keep track of changes in b

I'm using postgresql 9.2 and sqlalchemy 0.9.0.
In addition to some help, a link to the documentation — the section which deals with this issue — would be great so I can read it in detail. :-)

A: It seems to be like you need to read some of SQLAlchemy's native documentation. It is very well written and helps with a lot of problems, especially such basic ones. There are two absolute must-reads when working with the ORM:


*

*Object Relational Tutorial

*Using the Session
You have to read these before getting into SQLAlchemy.
The next thing before I address your problem:
proxy =  this_session.execute("select * from base_url where id = {0}".format(value))

Never, ever, do this! This makes you vulnerable to SQL Injection attacks and you don't want that, especially if you have such a might ORM taking care of it for you. There are several ways to work with that instead. The most simple way is to use bound parameters as documented for Session.execute:
proxy =  this_session.execute("select * from base_url where id = :value", {"value": value})

You could also use the SQLAlchemy core directly to create nice statements. For that you might want to read the also excellent SQL Expression Language Tutorial.
And now to your actual issue:
this_session.add(b)

This is what you wanted with attach: The object is added to the session (and database). Removing is twofold: If you want to delete it from the database:
this_session.delete(b)

If you just want to detach it from the session:
this_session.expunge(b)

But normally, one doesn't to remove them from the session except if adding them to a new session again. For the normal use-case this is not necessary to know but is also very well documented so it's easy to read up on it.
On SQL Injection (or why bound parameters are important):
I will only briefly state the problem, for a more extensive explanation please search yourself as there are plenty of resources.
The problem: Imagine you could set value to anything. You could also set it to literal SQL statements, for example:
value = "0 UNION SELECT * FROM admin_table"

If this runs it will produce:
"select * from base_url where id = 0 UNION SELECT * FROM admin_table"

I just gave an example here, but imagine this table contains your administrative credentials. There is so much more you can do and it is all bad. But now let's look how bound parameters do that:
"select * from base_url where id = '0 UNION SELECT * FROM admin_table'"

You see, it get's quoted. Yes you could quote it too, but this takes even care of that (read up if you are interested, else just do it this way).
On Session.add:
You are right, if you create an object that already exists (why would you do that?) then SQLAlchemy will try to add it (because it doesn't know you created something existing, it assumed you would retrieve it by querying). So if this is really you use case, then either Session.merge can possibly help you or you have to work with the states of objects (i.e. make it "not transient"). But before attempting to do so, please read the documentation linked above, because everything I explained (and way more) is explained there in much better ways.
