[sqlalchemy] Re: Can't shake off the 'MySQL server has gone away' Error

2008-08-18 Thread Alen Ribic

I still seem to get the 'MySQL server has gone away' Error.
I am suspecting that the problem is in my use of FCGI in production.
Thats the only difference between my Development environment and
Production and it works 100% without the error in Development env.

I guess I'll have to put some more debugging in my application in
Production setup.

Oh and, after the 'MySQL server has gone away' Error, I immediately
get the InvalidRequestError: Can't reconnect until invalid
transaction is rolled back.

SQLAlchemy version I'm running by the way is '0.4.6'.

I created a WSGI middleware class that handles the SQLAlchemy
Connections and Sessions like so:
Note: the middleware instance gets loaded only once on start of the
application. And the get_engine() method lazy-loads the engine once
and then returns existing thereafter.

sql.py


class SQLAlchemyMiddleware(object):

Middleware for providing clean SQLAlchemy Session objects for each
Request.

def __init__(self, application):
self.application = application
self.__engine = None

def get_engine(self):
if self.__engine is None:
self.__engine = create_engine(
settings.SQLALCHEMY_DEFAULT_URL,
pool_recycle=3600,
pool_size=20,
echo_pool=True
)
return self.__engine

def init_model(self, engine):
Call before using any of the tables or classes in the
model.
sm = orm.sessionmaker(autoflush=True, transactional=True,
bind=engine)

meta.engine = engine
meta.Session = orm.scoped_session(sm)

def __call__(self, environ, start_response):
try:
engine = self.get_engine()
self.init_model(engine)
return self.application(environ, start_response)
finally:
if meta.Session is not None:
meta.Session.remove()



models/meta.py


from sqlalchemy import MetaData

__all__ = ['engine', 'metadata', 'Session']

engine = None# Global metadata. If you have multiple databases with
overlapping table
# names, you'll need a metadata for each database.

Session = None

metadata = MetaData()



Regards,
-Alen

On Aug 15, 4:44 pm, Alen Ribic [EMAIL PROTECTED] wrote:
  one-per-application level

 That seems to have worked. I'll monitor the log for the next day or so
 and see how it goes.

 Thx

 -Alen

 On Aug 15, 4:27 pm, Michael Bayer [EMAIL PROTECTED] wrote:

  On Aug 15, 2008, at 10:21 AM, Alen Ribic wrote:

   To me it seems like the connections are not being returned back to the
   pool.
   Here is my engine code which gets called on each user HTTP request:

   engine = create_engine(
  settings.SQLALCHEMY_URL,
  pool_recycle=3600,
  pool_size=20,
  echo_pool=True
   )

  if you call create_engine() on every request, then you're creating a
  new connection pool for every request.  move this up to the module one-
  per-application level.
--~--~-~--~~~---~--~~
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: Can't shake off the 'MySQL server has gone away' Error

2008-08-18 Thread Michael Bayer


On Aug 18, 2008, at 5:08 AM, Alen Ribic wrote:


 sql.py
 

 class SQLAlchemyMiddleware(object):

Middleware for providing clean SQLAlchemy Session objects for each
 Request.

def __init__(self, application):
self.application = application
self.__engine = None

def get_engine(self):
if self.__engine is None:
self.__engine = create_engine(
settings.SQLALCHEMY_DEFAULT_URL,
pool_recycle=3600,
pool_size=20,
echo_pool=True
)
return self.__engine

def init_model(self, engine):
Call before using any of the tables or classes in the
 model.
sm = orm.sessionmaker(autoflush=True, transactional=True,
 bind=engine)

meta.engine = engine
meta.Session = orm.scoped_session(sm)

def __call__(self, environ, start_response):
try:
engine = self.get_engine()
self.init_model(engine)
return self.application(environ, start_response)
finally:
if meta.Session is not None:
meta.Session.remove()


The big mistake here is creating a brand new ScopedSession on each  
request.  This is not how ScopedSession was intended to be used; its  
created, like Engine, once per application.  Some details on this  
pattern are here:

http://www.sqlalchemy.org/docs/05/session.html#unitofwork_contextual_lifespan

The way you have it, a concurrent thread can easily interrupt the  
ScopedSession instance attached to meta and replace with a new one,  
with the old one being lost.

Here's a more reasonable approach:

class SQLAlchemyMiddleware(object):
def __init__(self, application):
self.application = application
meta.engine = create_engine(
   settings.SQLALCHEMY_DEFAULT_URL,
   pool_recycle=3600,
   pool_size=20,
   echo_pool=True
   )
 meta.Session =  
orm.scoped_session(orm.sessionmaker(autoflush=True, transactional=True,
 bind=meta.engine))

def __call__(self, environ, start_response):
try:
return self.application(environ, start_response)
except:
meta.Session.rollback()
raise
finally:
meta.Session.remove()





--~--~-~--~~~---~--~~
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: Can't shake off the 'MySQL server has gone away' Error

2008-08-18 Thread Alen Ribic

 The way you have it, a concurrent thread can easily interrupt the
 ScopedSession instance attached to meta and replace with a new one,
 with the old one being lost.

Ouch, that would be no good. Thank goodness my prod env aint really
prod yet.
Thank you for your help again. Much appreciated.

-Alen


On Aug 18, 3:13 pm, Michael Bayer [EMAIL PROTECTED] wrote:
 On Aug 18, 2008, at 5:08 AM, Alen Ribic wrote:





  sql.py
  

  class SQLAlchemyMiddleware(object):
 
 Middleware for providing clean SQLAlchemy Session objects for each
  Request.
 
 def __init__(self, application):
 self.application = application
 self.__engine = None

 def get_engine(self):
 if self.__engine is None:
 self.__engine = create_engine(
 settings.SQLALCHEMY_DEFAULT_URL,
 pool_recycle=3600,
 pool_size=20,
 echo_pool=True
 )
 return self.__engine

 def init_model(self, engine):
 Call before using any of the tables or classes in the
  model.
 sm = orm.sessionmaker(autoflush=True, transactional=True,
  bind=engine)

 meta.engine = engine
 meta.Session = orm.scoped_session(sm)

 def __call__(self, environ, start_response):
 try:
 engine = self.get_engine()
 self.init_model(engine)
 return self.application(environ, start_response)
 finally:
 if meta.Session is not None:
 meta.Session.remove()

 The big mistake here is creating a brand new ScopedSession on each
 request.  This is not how ScopedSession was intended to be used; its
 created, like Engine, once per application.  Some details on this
 pattern are here:

 http://www.sqlalchemy.org/docs/05/session.html#unitofwork_contextual_...

 The way you have it, a concurrent thread can easily interrupt the
 ScopedSession instance attached to meta and replace with a new one,
 with the old one being lost.

 Here's a more reasonable approach:

 class SQLAlchemyMiddleware(object):
 def __init__(self, application):
 self.application = application
 meta.engine = create_engine(
settings.SQLALCHEMY_DEFAULT_URL,
pool_recycle=3600,
pool_size=20,
echo_pool=True
)
  meta.Session =
 orm.scoped_session(orm.sessionmaker(autoflush=True, transactional=True,
  bind=meta.engine))

 def __call__(self, environ, start_response):
 try:
 return self.application(environ, start_response)
 except:
 meta.Session.rollback()
 raise
 finally:
 meta.Session.remove()
--~--~-~--~~~---~--~~
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: Can't shake off the 'MySQL server has gone away' Error

2008-08-18 Thread jason kirtland

Alen Ribic wrote:
 I still seem to get the 'MySQL server has gone away' Error.
 I am suspecting that the problem is in my use of FCGI in production.
 Thats the only difference between my Development environment and
 Production and it works 100% without the error in Development env.
 
 I guess I'll have to put some more debugging in my application in
 Production setup.

MySQL will also throw that error when a query needs more resources than 
the configuration allows.  If there's more data in your production 
environment or the my.cnf differs that could be it.  In any case, 
enabling error logging for the MySQL server process may shed some light 
on the root cause.

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