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