[sqlalchemy] Re: How to use SessionContextExt with cherrypy?

2007-07-25 Thread alex.schenkman

Thanks again for you enlightening answer.
I had no understanding for these different scopes.

What I haven't managed is to call a db function from a session/query
object.

I had the following line in my code, but it doesn't work anymore.
select([func.max(table.c.DocID)]).execute().scalar()

How would I call the max function having a query or session object, as
in the example below?

Thanks again!


from sqlalchemy import *

metadata = MetaData()
docs = Table('docs', metadata)
docs.append_column(Column('DocID', Integer, primary_key=True))
docs.append_column(Column('Path', String(120)))
docs.append_column(Column('Complete', Boolean))

class Doc(object):
def __init__(self, id, path, state):
self.DocID = id
self.Path = path
self.Complete = state

def __str__(self):
return '(%s) %s %s' %(self.DocID, self.Path, self.Complete)

if __name__ == "__main__":
mapper(Doc, docs)

db = create_engine( 'sqlite:///mydb' )
db.echo = False

s = create_session(bind_to = db)
q = s.query(Doc)



On Jul 24, 6:36 pm, Michael Bayer <[EMAIL PROTECTED]> wrote:
> On Jul 24, 2007, at 12:09 PM, alex.schenkman wrote:
>
> > class Session(object):
> > def __init__(self, name):
> > self.db = create_engine( 'sqlite:///%s' % name )
> > self.db.echo = False
> > self.metadata = BoundMetaData(self.db)
> > self.session = create_session()
> > self.db.docs = Table('docs', self.metadata, autoload=True)
> > self.db.mapper = mapper(Document, self.myDB.docs)
>
> mappers are at the same level at which your mapped class is defined.
> So if you define your Document class at the module level, so must
> your Mapper be defined.  also, if you defined classes and mappers
> within a function for each session, that wouldnt scale anyway since
> the mappers get stored in a global registry and youd run out of
> memory after many distinct users visited the site.
>
> so if your mapper is at the module level, so are your Tables and
> MetaData.   Sessions are not; so bind your individual sessions to the
> engines directly.  (Engines are usually module level too, but in this
> case you are opening many individual sqlite files so theyre local to
> your Session object)
>
> metadata = MetaData()
> class Document(object):
> pass
>
> # cant autoload=True here unless you have a specific SQLite file that
> is safe to use.  doesnt your
> # system need to create the tables inside the sqlite databases anyway ?
> docs = Table('docs', metadata,
> Column(...)
> )
>
> mapper(Document, docs)
>
> class Session(object):
> def __init__(self, name):
> self.db = create_engine('sqlite:///%s' % name)
> self.session = create_session(bind = self.db)
>
> thats it.  you dont need to reference "mapper" anywhere, just
> "self.session" and maybe "docs".


--~--~-~--~~~---~--~~
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: How to use SessionContextExt with cherrypy?

2007-07-24 Thread Michael Bayer


On Jul 24, 2007, at 12:09 PM, alex.schenkman wrote:

> class Session(object):
> def __init__(self, name):
> self.db = create_engine( 'sqlite:///%s' % name )
> self.db.echo = False
> self.metadata = BoundMetaData(self.db)
> self.session = create_session()
> self.db.docs = Table('docs', self.metadata, autoload=True)
> self.db.mapper = mapper(Document, self.myDB.docs)
>

mappers are at the same level at which your mapped class is defined.   
So if you define your Document class at the module level, so must  
your Mapper be defined.  also, if you defined classes and mappers  
within a function for each session, that wouldnt scale anyway since  
the mappers get stored in a global registry and youd run out of  
memory after many distinct users visited the site.

so if your mapper is at the module level, so are your Tables and  
MetaData.   Sessions are not; so bind your individual sessions to the  
engines directly.  (Engines are usually module level too, but in this  
case you are opening many individual sqlite files so theyre local to  
your Session object)


metadata = MetaData()
class Document(object):
pass

# cant autoload=True here unless you have a specific SQLite file that  
is safe to use.  doesnt your
# system need to create the tables inside the sqlite databases anyway ?
docs = Table('docs', metadata,
Column(...)
)

mapper(Document, docs)

class Session(object):
def __init__(self, name):
self.db = create_engine('sqlite:///%s' % name)
self.session = create_session(bind = self.db)

thats it.  you dont need to reference "mapper" anywhere, just  
"self.session" and maybe "docs".



--~--~-~--~~~---~--~~
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: How to use SessionContextExt with cherrypy?

2007-07-24 Thread alex.schenkman

Thanks for taking the time to answer this. I have had a frustrating
day and this gives me hope again, =)

I'm not trying to move objects between sessions.
I might be misunderstanding the APIs here, but what I think I need is
the following:

Two persons surf to my site at the same time and I keep some session-
specific data in an SQLite3 file.
One SQLite3 file per person/session.

(I know that CherryPy stores session info and I'm using it now, but
this part of the code was written before I understood that.)

So for each new person/session I instantiate the following class which
I then keep in memory through CherryPy session management.


class Session(object):
def __init__(self, name):
self.db = create_engine( 'sqlite:///%s' % name )
self.db.echo = False
self.metadata = BoundMetaData(self.db)
self.session = create_session()
self.db.docs = Table('docs', self.metadata, autoload=True)
self.db.mapper = mapper(Document, self.myDB.docs)


The second time I instantiate this class I get an error saying that
the class has already a primary mapper defined, which is true.

How do I go around this?
Thanks again!

On Jul 24, 4:47 pm, Michael Bayer <[EMAIL PROTECTED]> wrote:
> theres multiple levels of issues with this.
>
> one is, its not very clean to move objects between databases using
> sessions.   to do so, you have to remove the "_instance_key" of the
> object and save it into the other session:
>
> f = Foo()
> sess1.save(f)
> sess1.flush()
>
> sess1.expunge(f)
> del f._instance_key
> sess2.save(f)
> sess2.flush()
>
> the second is, a mapper does not define *where* you are storing your
> object, it only defines *how*.  therefore you *never* make a second
> mapper for a class, unless you are using one of two very specific
> recipes which are mentioned in the docs (which this example is not).
>
> third, the SessionContextExt shouldnt really "interfere" with this
> operation, in that it wont prevent you from expunging the object from
> one session and saving it into another, but it does make it
> confusing.  SessionContextExt is just the tiniest little convenience
> feature, that of "your objects automatically get saved into a
> session" and also "lazy loaders know how to find a session".  but if
> you are moving objects between sessions i would think its just going
> to confuse matters since its making decisions for you behind the
> scenes.  i think its important to try to make your code work while
> using the minimal (minimal here meaning, "none") number of "add-ons"
> to start with, so that you have something which works and can be
> understood.  then the add-ons can be implemented afterwards, as the
> need for them arises.
>
> On Jul 24, 2007, at 10:18 AM, alex.schenkman wrote:
>
>
>
> > Hi:
>
> > I'm new writing web apps and I'm using cherrypy with sqlalchemy.
> > As I understand it, each user navigating the site and clicking on
> > pages gets a new thread and thus it is necesary to  use sqlalchemy in
> > a thread-safe manner.
>
> > After reading the docs I assume that I have to use SessionContextExt,
> > but I don't figure out how.
>
> > As a test I try to write records to two different databases, but I
> > always get  a mapper error.
>
> > sqlalchemy.exceptions.ArgumentError: Class ''
> > already has a primary mapper defined with entity name 'None'.
>
> > Any hint is much appreciated!!
>
> > This is the code I try:
>
> > from sqlalchemy import *
> > from sqlalchemy.ext.sessioncontext import SessionContext
>
> > class Doc(object):
> > def __init__(self, id, path, state):
> > self.DocID = id
> > self.Path = path
> > self.Complete = state
>
> > if __name__ == "__main__":
> > db1 = create_engine( 'sqlite:///test.db' )
> > db1.echo = False
> > metadata = BoundMetaData( db1 )
> > docs = Table('docs', metadata, autoload=True)
>
> > ctx1 = SessionContext(create_session)
> > mapper(Doc, docs, extension=ctx1.mapper_extension)
> > d = Doc(43,'/etc/password',True)
> > ctx1.current.flush()
>
> > db2 = create_engine( 'sqlite:///test2.db' )
> > db2.echo = False
> > metadata2 = BoundMetaData( db2 )
>
> > d = Doc(15,'/etc/init',False)
>
> > ctx2 = SessionContext(create_session)
> > mapper(Doc, docs, extension=ctx2.mapper_extension)
> > ctx2.current.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: How to use SessionContextExt with cherrypy?

2007-07-24 Thread Michael Bayer


theres multiple levels of issues with this.

one is, its not very clean to move objects between databases using  
sessions.   to do so, you have to remove the "_instance_key" of the  
object and save it into the other session:

f = Foo()
sess1.save(f)
sess1.flush()

sess1.expunge(f)
del f._instance_key
sess2.save(f)
sess2.flush()

the second is, a mapper does not define *where* you are storing your  
object, it only defines *how*.  therefore you *never* make a second  
mapper for a class, unless you are using one of two very specific  
recipes which are mentioned in the docs (which this example is not).

third, the SessionContextExt shouldnt really "interfere" with this  
operation, in that it wont prevent you from expunging the object from  
one session and saving it into another, but it does make it  
confusing.  SessionContextExt is just the tiniest little convenience  
feature, that of "your objects automatically get saved into a  
session" and also "lazy loaders know how to find a session".  but if  
you are moving objects between sessions i would think its just going  
to confuse matters since its making decisions for you behind the  
scenes.  i think its important to try to make your code work while  
using the minimal (minimal here meaning, "none") number of "add-ons"  
to start with, so that you have something which works and can be  
understood.  then the add-ons can be implemented afterwards, as the  
need for them arises.

On Jul 24, 2007, at 10:18 AM, alex.schenkman wrote:

>
> Hi:
>
> I'm new writing web apps and I'm using cherrypy with sqlalchemy.
> As I understand it, each user navigating the site and clicking on
> pages gets a new thread and thus it is necesary to  use sqlalchemy in
> a thread-safe manner.
>
> After reading the docs I assume that I have to use SessionContextExt,
> but I don't figure out how.
>
> As a test I try to write records to two different databases, but I
> always get  a mapper error.
>
> sqlalchemy.exceptions.ArgumentError: Class ''
> already has a primary mapper defined with entity name 'None'.
>
> Any hint is much appreciated!!
>
>
> This is the code I try:
>
> from sqlalchemy import *
> from sqlalchemy.ext.sessioncontext import SessionContext
>
> class Doc(object):
> def __init__(self, id, path, state):
> self.DocID = id
> self.Path = path
> self.Complete = state
>
> if __name__ == "__main__":
> db1 = create_engine( 'sqlite:///test.db' )
> db1.echo = False
> metadata = BoundMetaData( db1 )
> docs = Table('docs', metadata, autoload=True)
>
>
> ctx1 = SessionContext(create_session)
> mapper(Doc, docs, extension=ctx1.mapper_extension)
> d = Doc(43,'/etc/password',True)
> ctx1.current.flush()
>
>
> db2 = create_engine( 'sqlite:///test2.db' )
> db2.echo = False
> metadata2 = BoundMetaData( db2 )
>
> d = Doc(15,'/etc/init',False)
>
> ctx2 = SessionContext(create_session)
> mapper(Doc, docs, extension=ctx2.mapper_extension)
> ctx2.current.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
-~--~~~~--~~--~--~---