Re: [sqlalchemy] Events (load and after_attach) for instance stamping

2013-01-11 Thread YKdvd
On Friday, January 11, 2013 2:58:31 PM UTC-4, Michael Bayer wrote:

> whoops, forgot the propagate flag:
>
> event.listen(Base, "load", My_load_instance_handler, propagate=True)
>
> That seems to do the trick.  I'd seen mention of propagate flags while 
wandering through the event docs, but the session event I started with 
didn't need it, and it didn't come to mind.  Thanks again. 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/UiscTL28-ZAJ.
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] Events (load and after_attach) for instance stamping

2013-01-11 Thread Michael Bayer

On Jan 11, 2013, at 11:35 AM, YKdvd wrote:

> On Friday, January 11, 2013 11:25:06 AM UTC-4, Michael Bayer wrote:
> 
> in theory.  It's new stuff and was very tricky to get it to work, so feel 
> free to send a brief test along.
> 
> Here's a minimal example I quickly put together - it retrieves from the 
> database, but the handler doesn't seem to fire, and so the print statement on 
> the second-last line fails.  I'm using the standard MySQLdb with MySQL 5.0.43 
> (sigh, they promise to update soon) - the server is on a Debian box, and the 
> client code is running in Python 1.6.4 on Windows 7 (it's actually the 64-bit 
> Python interpreter bundled with the Maya graphics package):
> 
> from sqlalchemy.ext.declarative import declarative_base
> from sqlalchemy import Table, Column, Integer, event, create_engine
> from sqlalchemy.orm import sessionmaker
> 
> def My_load_instance_handler(instance, context):
>   instance.itsProduction = None   #should add itsProduction attribute to 
> all loaded instances
>   print "stamped loaded instance with production"
> 
> AlchemyBase = declarative_base()
> event.listen(AlchemyBase, "load", My_load_instance_handler)

whoops, forgot the propagate flag:

event.listen(Base, "load", My_load_instance_handler, propagate=True)



-- 
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] Events (load and after_attach) for instance stamping

2013-01-11 Thread YKdvd
On Friday, January 11, 2013 11:25:06 AM UTC-4, Michael Bayer wrote:

>
> in theory.  It's new stuff and was very tricky to get it to work, so feel 
> free to send a brief test along.
>

Here's a minimal example I quickly put together - it retrieves from the 
database, but the handler doesn't seem to fire, and so the print statement 
on the second-last line fails.  I'm using the standard MySQLdb with MySQL 
5.0.43 (sigh, they promise to update soon) - the server is on a Debian box, 
and the client code is running in Python 1.6.4 on Windows 7 (it's actually 
the 64-bit Python interpreter bundled with the Maya graphics package):

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Table, Column, Integer, event, create_engine
from sqlalchemy.orm import sessionmaker

def My_load_instance_handler(instance, context):
instance.itsProduction = None #should add itsProduction attribute to all 
loaded instances
print "stamped loaded instance with production"

AlchemyBase = declarative_base()
event.listen(AlchemyBase, "load", My_load_instance_handler)
dbURL = "mysql://User:password@%s/%s" % ("dbServer", "dbName")  #replace 
with actual parameters
engine = create_engine(dbURL)
AlchemyBase.metadata.bind=engine

class MyDataClass(AlchemyBase):
__tablename__ = "vw_users"  #replace with actual table name
id = Column(Integer, primary_key=True)

Session = sessionmaker(bind=engine)
session = Session()
instance = session.query(MyDataClass).first()
print instance.id, instance.itsProduction #this fails with no itsProduction 
attribute
session.close()

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/GOcqdckIB0YJ.
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] Events (load and after_attach) for instance stamping

2013-01-11 Thread Michael Bayer

On Jan 11, 2013, at 2:26 AM, YKdvd wrote:

> On Friday, January 11, 2013 2:34:09 AM UTC-4, Michael Bayer wrote:
> 
> > you can associate the instance event with the mapper() callable or Mapper 
> > class, and it will take effect for all mapped classes. 
> 
> I think that would work for my case, although I'm a little fuzzy as to the 
> exact syntax to provide the mapper reference for event.listen - I've just 
> been using declarative and haven't dealt with mappers directly - each of my 
> classes would have a different mapper instance, and I'd have to attach to 
> each (no benefit over class attachment)?  Or using the Mapper class itself 
> would trigger for anything mapped, and I'd have to discriminate in the 
> handler for classes of interest, or create a Mapper subclass and somehow have 
> my declarative_base subclass use it?  

the events just assign special meaning to the actual mapper() function:

from sqlalchemy.orm import mapper

@event.listens_for(mapper, "init")
def foo(...)


-- 
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] Events (load and after_attach) for instance stamping

2013-01-11 Thread Michael Bayer

On Jan 11, 2013, at 10:19 AM, YKdvd wrote:

> That sounds even nicer, and since I'm just starting out with no legacy code 
> I've been meaning to try dropping 0.8 in even before it is final.  It sounds 
> like I could just do something like event.listen(MyDeclarativeSubclass, 
> "load", myStamperFunc).
> 
>  I popped in 0.8b2 and tried something like this:
> 
> class SubBase(object):
> ...
> def MyLoadHandler(instance, context):
>print "hit the load handler"
> MyBase = declarative_base(cls=SubBase)
> event.listen(MyBase, "load", MyLoadHandler)
> ...
> class MyDataClass(MyBase):
> ... do all the declarative stuff
> ...
> anInstance=session.query(MyDataClass).first()
> 
> 
> It doesn't complain about a non-existent event when I install the handler, 
> but the event handler doesn't seem to get called when the instance gets 
> loaded with the query.  I'll try and do a minimal little standalone test to 
> make sure it isn't something in my system messing things up, but in theory 
> this should work?


in theory.  It's new stuff and was very tricky to get it to work, so feel free 
to send a brief test along.



> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To view this discussion on the web visit 
> https://groups.google.com/d/msg/sqlalchemy/-/rQwgslRRDGsJ.
> 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] Events (load and after_attach) for instance stamping

2013-01-11 Thread YKdvd

>
> That sounds even nicer, and since I'm just starting out with no legacy 
> code I've been meaning to try dropping 0.8 in even before it is final.  It 
> sounds like I could just do something like 
> event.listen(MyDeclarativeSubclass, "load", myStamperFunc).
>

 I popped in 0.8b2 and tried something like this:

class SubBase(object):
...
def MyLoadHandler(instance, context):
   print "hit the load handler"
MyBase = declarative_base(cls=SubBase)
event.listen(MyBase, "load", MyLoadHandler)
...
class MyDataClass(MyBase):
... do all the declarative stuff
...
anInstance=session.query(MyDataClass).first()


It doesn't complain about a non-existent event when I install the handler, 
but the event handler doesn't seem to get called when the instance gets 
loaded with the query.  I'll try and do a minimal little standalone test to 
make sure it isn't something in my system messing things up, but in theory 
this should work?

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/rQwgslRRDGsJ.
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] Events (load and after_attach) for instance stamping

2013-01-10 Thread YKdvd
On Friday, January 11, 2013 2:34:09 AM UTC-4, Michael Bayer wrote:
>
>
> > you can associate the instance event with the mapper() callable or 
> Mapper class, and it will take effect for all mapped classes. 


I think that would work for my case, although I'm a little fuzzy as to the 
exact syntax to provide the mapper reference for event.listen - I've just 
been using declarative and haven't dealt with mappers directly - each of my 
classes would have a different mapper instance, and I'd have to attach to 
each (no benefit over class attachment)?  Or using the Mapper class itself 
would trigger for anything mapped, and I'd have to discriminate in the 
handler for classes of interest, or create a Mapper subclass and somehow 
have my declarative_base subclass use it?  

>  

Using 0.8 you can also associate the listener with a common base class, 
> such as your declarative Base, or even a mixin that's common to some subset 
> of classes. 
>

That sounds even nicer, and since I'm just starting out with no legacy code 
I've been meaning to try dropping 0.8 in even before it is final.  It 
sounds like I could just do something like 
event.listen(MyDeclarativeSubclass, "load", myStamperFunc).

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/Npq3NDrxh10J.
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] Events (load and after_attach) for instance stamping

2013-01-10 Thread Michael Bayer

On Jan 11, 2013, at 1:22 AM, YKdvd wrote:

> 
> SQLA's event system has the "after_attach" session event.  Hooking into this 
> works for new instances I attach to a session with add(), but does't fire 
> when items are loaded from a query - presumably "attached" means direct 
> userland attachment only, not instances being associated with a session via a 
> query. So it's only half the solution - there doesn't seem to be a 
> session-level  event that fires in the latter case?

there is not, you'd use the instance event

> 
> There is a "load" instance-level event, which seems to solve the other half 
> of this.  The QueryContext passed to the handler contains the session, and I 
> can stamp the instance with the Project reference I've stored in the session. 
>  The only drawback is that I apparently need to separately attach the event 
> listener to each project instance class?  

you can associate the instance event with the mapper() callable or Mapper 
class, and it will take effect for all mapped classes.

Using 0.8 you can also associate the listener with a common base class, such as 
your declarative Base, or even a mixin that's common to some subset of classes.

The approach of listening for configured mappers and then associating the 
instance event at that point works as well too but hopefully that shouldn't be 
necessary here.


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



[sqlalchemy] Events (load and after_attach) for instance stamping

2013-01-10 Thread YKdvd
In the MySQL system I'm redoing with SQLAlchemy, there is effectively a 
"master' schema that exists once top-level stuff (including a table 
describing projects) , and "project" schemas (one identical set of tables 
per project), which have project-level stuff.  When an object is retrieved 
from a project, there is nothing in the data itself which indicates which 
project it was loaded from, but this may in certain cases be needed.  I 
have a nice collection of Project objects loaded from the master schema 
lying around, and I pass my own subclass of SQLA's Session to 
sessionmaker() so I can store a reference to the appropriate Project with a 
session.  But since Detached and Transient instances don't have an 
associated session, I can't just use object_session() to access the Project 
via the instance's session.  So I thought I'd stamp a reference to the 
appropriate Project onto instances.

SQLA's event system has the "after_attach" session event.  Hooking into 
this works for new instances I attach to a session with add(), but does't 
fire when items are loaded from a query - presumably "attached" means 
direct userland attachment only, not instances being associated with a 
session via a query. So it's only half the solution - there doesn't seem to 
be a session-level  event that fires in the latter case?

There is a "load" instance-level event, which seems to solve the other half 
of this.  The QueryContext passed to the handler contains the session, and 
I can stamp the instance with the Project reference I've stored in the 
session.  The only drawback is that I apparently need to separately attach 
the event listener to each project instance class?  Presumably I could 
somehow retrieve a list of classes from the declarative_base 
(_decl_class_registry_ ?) and walk through that adding the listeners.

Is this a reasonable approach, and between the two events I'll be seeing 
all the objects that enter the session either from database retrieval or my 
code?


-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/_F71NtWi9MsJ.
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.