Ricardo, Your use case has been useful to pinpoint some issues with the semantic of commit/rollback/close in the DAL. We are working on it to improve ease of use. So thank you!
mic 2013/9/27 Ricardo Cárdenas <ricardo.carde...@gmail.com> > @michele, @niphlod, @Derek > > My solution oddly turned out to be a combination of all of your > suggestions! :) > > On Postgres, Michele's snippet below works for me too. On MySQL it works, > but then raises an exception (attached below). Apparently, upon exit web2py > tries to close the dead MySQL connection, and MySQL complains (even though > the connection had no outstanding transactions). The PostgreSQL behavior > seems different; web2py is silent when trying to close a dead connection > with no outstanding transactions. > > So I tried db._adapter.close() right after the db.commit(). That > eliminated the MySQL exception. In fact, if there are no pending > transactions, db._adapter.close() is all that is needed. > > Problem solved for me. But I wonder whether the dev's might consider > exposing an explicit db.close() and db.open() to avoid calling > db._adapter.close() > and then DAL(...auto_import=True), for the use case where a script does a > lot of processing sans database, and then resumes database use. > > Sorry if this was TL;DR for most people... best regards -Ricardo > > > > Traceback (most recent call last): > File "/home/rcardenas/web2py/gluon/shell.py", line 231, in run > BaseAdapter.close_all_instances('commit') > File "/home/rcardenas/web2py/gluon/dal.py", line 560, in > close_all_instances > db._adapter.close(action) > File "/home/rcardenas/web2py/gluon/dal.py", line 540, in close > getattr(self, action)() > File "/home/rcardenas/web2py/gluon/dal.py", line 1740, in commit > if self.connection: return self.connection.commit() > OperationalError: (2013, 'Lost connection to MySQL server during query') > > Traceback (most recent call last): > File "web2py.py", line 33, in <module> > gluon.widget.start(cron=True) > File "/home/rcardenas/web2py/gluon/widget.py", line 1120, in start > import_models=options.import_models, startfile=options.run) > File "/home/rcardenas/web2py/gluon/shell.py", line 235, in run > BaseAdapter.close_all_instances('rollback') > File "/home/rcardenas/web2py/gluon/dal.py", line 560, in > close_all_instances > db._adapter.close(action) > File "/home/rcardenas/web2py/gluon/dal.py", line 540, in close > getattr(self, action)() > File "/home/rcardenas/web2py/gluon/dal.py", line 1743, in rollback > if self.connection: return self.connection.rollback() > _mysql_exceptions.OperationalError: (2006, 'MySQL server has gone away') > > > > On Wednesday, September 25, 2013 8:36:01 AM UTC-5, Michele Comitini wrote: > >> >> >> ---------- Forwarded message ---------- >> From: Michele Comitini <michele....@gmail.com> >> Date: 2013/9/25 >> Subject: Re: [web2py] Re: batch script - best way to reopen a closed >> database connection? >> To: Ricardo Cárdenas >> >> Try using the auto_import >> >> see the following: >> >> db.commit() >> sleep(20) # <-- here I stop and restart the postgresql service >> db=DAL('postgres://script:**script@localhost/script',pool_**size=1, >> check_reserved=['all'], auto_import=True) >> print db(db.people).count() >> >> >> >> 2013/9/25 Ricardo Cárdenas <ricardo....@gmail.com> >> >> Hi Michele, you're right, it's better to instantiate the connection when >>> needed. >>> >>> Since I have all the DAL() and define_tables() calls in db.py, I >>> shouldn't have to rewrite the code elsewhere. I tried "import db" after the >>> wait, but I guess it's not possible to import models/* because I got an >>> import error. How do you suggest I implement your suggestion? >>> >>> thanks -Ricardo >>> >>> On Wednesday, September 25, 2013 4:50:38 AM UTC-5, Michele Comitini >>> wrote: >>> >>>> Yes, but the connection in the pool will get dropped anyway. After >>>> some thought IMHO the correct way for you to fix the problem is: >>>> <start> >>>> ...wait...wait... >>>> db = DAL(...) >>>> <use db> >>>> db.commit() #<- commit or rollback as soon as possible >>>> ...wait...wait... >>>> db = DAL(...) >>>> <use db> >>>> db.commit() #<- commit or rollback as soon as possible >>>> <and so on> >>>> >>>> i.e. init the db instance right before using it. This should avoid >>>> timing out connections, with consequent data loss. >>>> It fixes also the problem that keeping transactions open for such a >>>> long time is no good for anything else trying to work on that database it >>>> could cause all other connections/applications to stop until the >>>> transaction is closed or timedout! >>>> >>>> >>>> 2013/9/25 Ricardo Cárdenas <ricardo....@gmail.com> >>>> >>>> @michele - No, I'm not doing a db.commit() -- because I don't use the >>>>> db connection at all, until many minutes later, when it fails. >>>>> >>>>> However, you bring up an interesting point. Does this mean that if I >>>>> db.commit() at the very beginning of my script (even if there is no >>>>> outstanding transaction), I will in effect be pushing a connection to >>>>> sleep? >>>>> >>>>> Ricardo >>>>> >>>>> >>>>> On Tuesday, September 24, 2013 5:16:20 PM UTC-5, Michele Comitini >>>>> wrote: >>>>> >>>>>> Did you remember to do a commit at each round? >>>>>> >>>>>> A long running script / daemon can do: >>>>>> >>>>>> db=DAL... >>>>>> <define tables> >>>>>> >>>>>> while True: >>>>>> <do stuff with DAL> >>>>>> db.commit() >>>>>> sleep(1000) # <- just for exampl i.e. don't do anything for a long >>>>>> time >>>>>> >>>>>> The DAL pushes the connection "back to sleep in the pool" [ :-) ] >>>>>> when there is a commit. >>>>>> When one starts operating on the DAL instance (db) a connection is >>>>>> taken from the pool and *tested* for being functioning. >>>>>> If the connection is dead it's replaced by a new one. Then a >>>>>> transaction is started on that connection. >>>>>> >>>>>> mic >>>>>> >>>>>> >>>>>> 2013/9/24 Ricardo Cárdenas <ricardo....@gmail.com> >>>>>> >>>>>>> Derek, thanks for your suggestion. Which is the preferred way to >>>>>>> reopen the connection and define the tables? >>>>>>> >>>>>>> My db.py contains >>>>>>> >>>>>>> db = DAL(connection_string, options...) >>>>>>> db.define_table('table1', Field('f1' ...), Field('f2'...)) >>>>>>> db.define_table(...) >>>>>>> db.define_table(...) >>>>>>> ... >>>>>>> >>>>>>> So ideally I wouldn't have to repeat this code in my script. Is it >>>>>>> best I break out the DAL/define_tables calls into a file that I import >>>>>>> both >>>>>>> in my db.py and in my script.py? >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Tuesday, September 24, 2013 4:45:09 PM UTC-5, Derek wrote: >>>>>>>> >>>>>>>> Each time you need to do work, you should open a new connection. >>>>>>>> You'd think there is a large overhead in creating a connection, but >>>>>>>> there >>>>>>>> isn't. >>>>>>>> >>>>>>>> On Tuesday, September 24, 2013 2:33:24 PM UTC-7, Ricardo Cárdenas >>>>>>>> wrote: >>>>>>>>> >>>>>>>>> I have a web2py app running fine on pythonanywhere. I have a minor >>>>>>>>> problem - I think I understand why it is happening, but would seek >>>>>>>>> your >>>>>>>>> advice as to how best to fix it. >>>>>>>>> >>>>>>>>> The app itself works fine. But I also run a scheduled task using >>>>>>>>> PA's scheduler, by executing "python web2py.py -S appname -M -R >>>>>>>>> appname/private/myscript.py". The script does some processing for a >>>>>>>>> few >>>>>>>>> minutes, and only then starts writing to the MySQL database. >>>>>>>>> >>>>>>>>> PA's MySQL database has wait_timeout set to 120 seconds. If my >>>>>>>>> initial processing is less than wait_timeout, everything works fine. >>>>>>>>> But when my initial processing exceeds wait_timeout, I get a >>>>>>>>> 'Lost Connection to MySQL' error when my code tries to write to >>>>>>>>> the database. I am using connection pooling in the call to the DAL, >>>>>>>>> but I >>>>>>>>> guess the connection instantiated by db.py file is not automatically >>>>>>>>> kept >>>>>>>>> warm nor is it automatically replaced by another good connection when >>>>>>>>> it >>>>>>>>> expires. >>>>>>>>> >>>>>>>>> What's the best practice here: >>>>>>>>> >>>>>>>>> - Is there a preferred way to ping the database every once in >>>>>>>>> a while? >>>>>>>>> - Is there a preferred way to detect an expired DAL >>>>>>>>> connection, and to request another one? >>>>>>>>> >>>>>>>>> Thanks for any suggestions or pointers. Sorry if this is in the >>>>>>>>> docs, couldn't find it. warm regards -Ricardo >>>>>>>>> >>>>>>>>> -- >>>>>>> Resources: >>>>>>> - http://web2py.com >>>>>>> - http://web2py.com/book (Documentation) >>>>>>> - >>>>>>> http://github.com/web2py/**web2p****y<http://github.com/web2py/web2py>(Source >>>>>>> code) >>>>>>> - >>>>>>> https://code.google.com/p/**web2****py/issues/list<https://code.google.com/p/web2py/issues/list>(Report >>>>>>> Issues) >>>>>>> --- >>>>>>> You received this message because you are subscribed to the Google >>>>>>> Groups "web2py-users" group. >>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>> send an email to web2py+un...@**googlegroups.com. >>>>>>> >>>>>>> For more options, visit https://groups.google.com/**grou**** >>>>>>> ps/opt_out <https://groups.google.com/groups/opt_out>. >>>>>>> >>>>>> >>>>>> -- >>>>> Resources: >>>>> - http://web2py.com >>>>> - http://web2py.com/book (Documentation) >>>>> - >>>>> http://github.com/web2py/**web2p**y<http://github.com/web2py/web2py>(Source >>>>> code) >>>>> - >>>>> https://code.google.com/p/**web2**py/issues/list<https://code.google.com/p/web2py/issues/list>(Report >>>>> Issues) >>>>> --- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "web2py-users" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to web2py+un...@**googlegroups.com. >>>>> For more options, visit >>>>> https://groups.google.com/**grou**ps/opt_out<https://groups.google.com/groups/opt_out> >>>>> . >>>>> >>>> >>>> >> >> -- > Resources: > - http://web2py.com > - http://web2py.com/book (Documentation) > - http://github.com/web2py/web2py (Source code) > - https://code.google.com/p/web2py/issues/list (Report Issues) > --- > You received this message because you are subscribed to the Google Groups > "web2py-users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to web2py+unsubscr...@googlegroups.com. > > For more options, visit https://groups.google.com/groups/opt_out. > -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.