[web2py] Re: cPickle instead of return dict(D=D) in serverside ajax function: accessing it in View
It might help if you provide a little more detail regarding what D is and what kind of processing is going on. Why do you create D in the controller but newD in the view? Does D get used anywhere before newD is created? Could you just create newD in the controller as well? Is D/newD unique per user/session, or is it the same across all sessions? As it is, it looks like you could get a race condition. An initial request to func1 leaves newD in my_pckl.p. Then before the first Ajax request to func2, a second request to func1 overwrites my_pckl.p with D, and then the first Ajax request to func2 reads D out of my_pckl.p before the view changes it to newD (i.e., so the Ajax request gets D instead of newD). The problem is worse if the value of newD depends on the user/session -- since you always use the same filename, the newD for one user could be overwritten by a func1 request from another user before the first user's func2 Ajax request. The whole process will be slowed down a bit by the file writing/reading as well. If newD is the same for all users, you might store it in cache.ram rather than writing it to a file -- that will be faster and you won't have to worry about doing the pickling yourself. If newD is specific to each user, then just store it in the session (again, you won't have to pickle it yourself). Anthony On Saturday, February 11, 2012 4:31:08 AM UTC-5, Vineet wrote: > > From View, I am calling server side controller function via web2py's > ajax function with ':eval' > So far, so good. > > Further I need to return a dict from this ajax controller (in addition > to "return js"), > Then access this dict in View & process it. > Finally, return dict to another controller for server side processing. > > ++ > I am doing it like this. > > def func1(): > D = ({1:'a', 2:'b'}, {3:'c', 4:'d'}) > cPickle.dump(D, open( "my_pkcl.p", "wb")) > return dict() > > This D is accessed in 'View' and processed. > > (Why I am not using return dict(D=D)? > It is explained at the end.) > > {{newD = cPickle.load(open( "my_pkcl.p", "rb" ))}} > {{for i in newD:}} > ...processing statements... > {{pass}} > > After processing newD, it is again pickled with same filename. > {{cPickle.dump(newD, open( "my_pkcl.p", "wb" ) )}} > > Then ajax function is called-- > ajax("{{=URL('func2)}}", [], ":eval"); > > def func2(): > # access the D which has been changed by 'View' code > changedD = cPickle.load( open( "my_pkcl.p", "rb" ) ) > ... > ... > process changedD as per requirement > > ++ > Why I am not using return dict(D=D)? > While calling 'func2' via web2py's ajax function, I can't pass the > Dict (or any other python object) as argument or vars. > So I resorted to cPickle it. > +++ > My question is:-- > I am cPickling in controller & loading (unpickling) in View. > After processing in view, cPickling it & again loading (unpickling) in > controller. > > Is it OK or is it weired / horrible (considering speed & good coding > practice) ? > If not OK, how do I do it with any alternative method ? > > Thanks, > > Vineet
[web2py] Re: cPickle instead of return dict(D=D) in serverside ajax function: accessing it in View
Thanks Anthony. Here's the explanation of what I intend to do. 1) D is a dataset (tuple of dicts) obtained from MySQL. I am using a 3rd party lib viz. 'DABO' for database interaction + business-logic tier. So, D is generated by controller function. 2) It is passed to View where HTML elements are populated by the data from this dataset. 3) User interacts with HTML elements & changes the data. 4) Dynamically, the dataset is altered after user-interaction with HTML elements. 5) After hitting 'Save' button, the dataset is passed to controller function for handling add/update/delete on related DB tables. This way, a dataset is unique for every session. I hope my logic is now more clear. I appreciate your hint on using session object for storing this dataset. Any thoughts / suggestions/ corrections please. --- Vineet On Feb 11, 6:22 pm, Anthony wrote: > It might help if you provide a little more detail regarding what D is and > what kind of processing is going on. Why do you create D in the controller > but newD in the view? Does D get used anywhere before newD is created? > Could you just create newD in the controller as well? Is D/newD unique per > user/session, or is it the same across all sessions? > > As it is, it looks like you could get a race condition. An initial request > to func1 leaves newD in my_pckl.p. Then before the first Ajax request to > func2, a second request to func1 overwrites my_pckl.p with D, and then the > first Ajax request to func2 reads D out of my_pckl.p before the view > changes it to newD (i.e., so the Ajax request gets D instead of newD). The > problem is worse if the value of newD depends on the user/session -- since > you always use the same filename, the newD for one user could be > overwritten by a func1 request from another user before the first user's > func2 Ajax request. The whole process will be slowed down a bit by the file > writing/reading as well. > > If newD is the same for all users, you might store it in cache.ram rather > than writing it to a file -- that will be faster and you won't have to > worry about doing the pickling yourself. If newD is specific to each user, > then just store it in the session (again, you won't have to pickle it > yourself). > > Anthony > > On Saturday, February 11, 2012 4:31:08 AM UTC-5, Vineet wrote: > > > From View, I am calling server side controller function via web2py's > > ajax function with ':eval' > > So far, so good. > > > Further I need to return a dict from this ajax controller (in addition > > to "return js"), > > Then access this dict in View & process it. > > Finally, return dict to another controller for server side processing. > > > ++ > > I am doing it like this. > > > def func1(): > > D = ({1:'a', 2:'b'}, {3:'c', 4:'d'}) > > cPickle.dump(D, open( "my_pkcl.p", "wb")) > > return dict() > > > This D is accessed in 'View' and processed. > > > (Why I am not using return dict(D=D)? > > It is explained at the end.) > > > {{newD = cPickle.load(open( "my_pkcl.p", "rb" ))}} > > {{for i in newD:}} > > ...processing statements... > > {{pass}} > > > After processing newD, it is again pickled with same filename. > > {{cPickle.dump(newD, open( "my_pkcl.p", "wb" ) )}} > > > Then ajax function is called-- > > ajax("{{=URL('func2)}}", [], ":eval"); > > > def func2(): > > # access the D which has been changed by 'View' code > > changedD = cPickle.load( open( "my_pkcl.p", "rb" ) ) > > ... > > ... > > process changedD as per requirement > > > ++ > > Why I am not using return dict(D=D)? > > While calling 'func2' via web2py's ajax function, I can't pass the > > Dict (or any other python object) as argument or vars. > > So I resorted to cPickle it. > > +++ > > My question is:-- > > I am cPickling in controller & loading (unpickling) in View. > > After processing in view, cPickling it & again loading (unpickling) in > > controller. > > > Is it OK or is it weired / horrible (considering speed & good coding > > practice) ? > > If not OK, how do I do it with any alternative method ? > > > Thanks, > > > Vineet > >
[web2py] Re: cPickle instead of return dict(D=D) in serverside ajax function: accessing it in View
> > 3) User interacts with HTML elements & changes the data. > > 4) Dynamically, the dataset is altered after user-interaction with > HTML elements. > In that case, this part of your view won't work: {{for i in newD:}} ...processing statements... {{pass}} {{cPickle.dump(newD, open( "my_pkcl.p", "wb" ) )}} Anything done in the web2py template language has to happen on the server (before sending the page to the browser), not in the client. cPickle.dump cannot be called from the browser -- that is strictly a server-side operation. Anything that happens on the client side has to be done via Javascript (and/or a standard form submission). > 5) After hitting 'Save' button, the dataset is passed to controller > function for handling add/update/delete on related DB tables. > This sounds fine. It's not clear you need to store the data in the session at all. It sounds like you can just load the data in the view, let the user make and submit changes, and then simply update the db with those changes. Anthony
[web2py] Re: cPickle instead of return dict(D=D) in serverside ajax function: accessing it in View
I see. That means neither cPickle nor session can be used. A workaround can be like this-- Keep the dataset stored in session. On client-side, after hitting the save button, collect the values of elements in JSON array format. I can't use request.vars.elmt, because I require to pass the class values also (of html elements) to the ajax controller. (These class values are set/altered after user-interaction.) web2py's ajax function can't pass JSON array to controller. Can you pl. tell how to pass JSON array to controller via ajax? (maybe $.ajax ?) Thanks, Vineet On Feb 11, 10:28 pm, Anthony wrote: > > 3) User interacts with HTML elements & changes the data. > > > 4) Dynamically, the dataset is altered after user-interaction with > > HTML elements. > > In that case, this part of your view won't work: > > {{for i in newD:}} > ...processing statements... > {{pass}} > {{cPickle.dump(newD, open( "my_pkcl.p", "wb" ) )}} > > Anything done in the web2py template language has to happen on the server > (before sending the page to the browser), not in the client. cPickle.dump > cannot be called from the browser -- that is strictly a server-side > operation. Anything that happens on the client side has to be done via > Javascript (and/or a standard form submission). > > > 5) After hitting 'Save' button, the dataset is passed to controller > > function for handling add/update/delete on related DB tables. > > This sounds fine. It's not clear you need to store the data in the session > at all. It sounds like you can just load the data in the view, let the user > make and submit changes, and then simply update the db with those changes. > > Anthony
[web2py] Re: cPickle instead of return dict(D=D) in serverside ajax function: accessing it in View
Google is your friend: http://stackoverflow.com/questions/7594740/convert-objects-to-json-and-send-via-jquery-ajax http://stackoverflow.com/questions/3168401/json-formatting-sending-json-via-jquery-ajax-post-to-java-wicket-server http://www.intelligrape.com/blog/2010/06/11/jquery-send-json-object-with-an-ajax-request/ On Sunday, February 12, 2012 10:54:48 AM UTC-5, Vineet wrote: > > I see. > That means neither cPickle nor session can be used. > > A workaround can be like this-- > Keep the dataset stored in session. > On client-side, after hitting the save button, collect the values of > elements in JSON array format. > I can't use request.vars.elmt, because I require to pass the class > values also (of html elements) to the ajax controller. > (These class values are set/altered after user-interaction.) > web2py's ajax function can't pass JSON array to controller. > > Can you pl. tell how to pass JSON array to controller via ajax? > (maybe $.ajax ?) > > Thanks, > > Vineet > > On Feb 11, 10:28 pm, Anthony wrote: > > > 3) User interacts with HTML elements & changes the data. > > > > > 4) Dynamically, the dataset is altered after user-interaction with > > > HTML elements. > > > > In that case, this part of your view won't work: > > > > {{for i in newD:}} > > ...processing statements... > > {{pass}} > > {{cPickle.dump(newD, open( "my_pkcl.p", "wb" ) )}} > > > > Anything done in the web2py template language has to happen on the > server > > (before sending the page to the browser), not in the client. > cPickle.dump > > cannot be called from the browser -- that is strictly a server-side > > operation. Anything that happens on the client side has to be done via > > Javascript (and/or a standard form submission). > > > > > 5) After hitting 'Save' button, the dataset is passed to controller > > > function for handling add/update/delete on related DB tables. > > > > This sounds fine. It's not clear you need to store the data in the > session > > at all. It sounds like you can just load the data in the view, let the > user > > make and submit changes, and then simply update the db with those > changes. > > > > Anthony
[web2py] Re: cPickle instead of return dict(D=D) in serverside ajax function: accessing it in View
Yeah. Let me dive into these links. Thanks, Vineet On Feb 12, 9:09 pm, Anthony wrote: > Google is your > friend:http://stackoverflow.com/questions/7594740/convert-objects-to-json-an...http://stackoverflow.com/questions/3168401/json-formatting-sending-js...http://www.intelligrape.com/blog/2010/06/11/jquery-send-json-object-w... > > > On Sunday, February 12, 2012 10:54:48 AM UTC-5, Vineet wrote: > > > I see. > > That means neither cPickle nor session can be used. > > > A workaround can be like this-- > > Keep the dataset stored in session. > > On client-side, after hitting the save button, collect the values of > > elements in JSON array format. > > I can't use request.vars.elmt, because I require to pass the class > > values also (of html elements) to the ajax controller. > > (These class values are set/altered after user-interaction.) > > web2py's ajax function can't pass JSON array to controller. > > > Can you pl. tell how to pass JSON array to controller via ajax? > > (maybe $.ajax ?) > > > Thanks, > > > Vineet > > > On Feb 11, 10:28 pm, Anthony wrote: > > > > 3) User interacts with HTML elements & changes the data. > > > > > 4) Dynamically, the dataset is altered after user-interaction with > > > > HTML elements. > > > > In that case, this part of your view won't work: > > > > {{for i in newD:}} > > > ...processing statements... > > > {{pass}} > > > {{cPickle.dump(newD, open( "my_pkcl.p", "wb" ) )}} > > > > Anything done in the web2py template language has to happen on the > > server > > > (before sending the page to the browser), not in the client. > > cPickle.dump > > > cannot be called from the browser -- that is strictly a server-side > > > operation. Anything that happens on the client side has to be done via > > > Javascript (and/or a standard form submission). > > > > > 5) After hitting 'Save' button, the dataset is passed to controller > > > > function for handling add/update/delete on related DB tables. > > > > This sounds fine. It's not clear you need to store the data in the > > session > > > at all. It sounds like you can just load the data in the view, let the > > user > > > make and submit changes, and then simply update the db with those > > changes. > > > > Anthony