|
Eric Baumer
ebaumer at ics.uci.edu
Wed Jul 30 17:34:49 EDT 2008
I was having trouble loading a pickled class object using mod_python
when I came across this post in the mod_python archives from June 2007.
even though the link below implies that loading a pickled object in this
manner cannot be done, I believe I may have found a work around. I
wanted to bounce this off the mod_python list for two reasons: (a) to
make sure I'm not breaking anything, and (b) to share what may be a
viable solution to this problem.
the link mentioned here seems to imply that one cannot load a pickled
instance of a class in a script running through mod_python. the problem
seems to be related to mod_python's method of importing. since there
doesn't seem to be a good way to guarantee where on the file system the
script will run when apache receives a request that invokes mod_python.
thus, rather than referring to a module by name alone (with the standard
"import module_name" approach), modules are referred to by their path on
the file system using apache.import_module, for example "my_module =
apache.import_module('/home/username/my_proj/my_module.py')".
the problem becomes that this method of importing doesn't register the
module name with sys.modules. therefore, if I have a pickled instance of
some class my_module.MyClass, when I try to load the pickled instance,
python would complain that there is "No module named my_module" (as
described by the OP), even if I had loaded it using apache.import_module.
the workaround that I found looks something like the following.
import sys
def index(req):
my_module = apache.import_module('/home/username/my_proj/my_module.py')
sys.modules['my_module'] = my_module
this code ensures that my_module is registered with the list of modules
python knows about in sys.modules, so that when I load that pickled
instance of my_module.MyClass, python knows about a module named
"my_module" and thus can properly load the class.
I should note that, in practice, this has actually worked for me.
whether or not it's a good idea, though, is another question.
what do you all think? have I gone horribly wrong, or is this a viable
work around to loading a pickled instance of a class?
~Eric
>> >/ Read:
>> />/
>> />/ http://www.dscpl.com.au/wiki/ModPython/Articles/IssuesWithSessionObjects
>> />/
>> />/ Although document was written in reference to sessions, they use
>> />/ pickle and thus it still applies.
>> />/
>> />/ Graham
>> /
>> Ok, that's a limitation, but I'll now I understand what happened !
>>
>> Thanks !
>>
>> Seb
> Hello !
>
> I've found something a bit strange in mod_python : the pickle
> instruction doesn't work when we want to save classes ( there is no
> problème with tupple or list.. )
>
> I made this code for explain it:
>
> -->
> import mod_python
> import pickle
>
> #Create a very simple class object
> class another_class:
>
> def __init__(self, text):
> self.text = text
>
> #Another one class
> class a_class:
>
> def __init__(self):
> self.elements = []
>
> #Add an element of the second class
> self.add_entry("test")
> self.save()
>
> def add_entry(self, name):
> self.elements.append( another_class(name) )
>
> def save(self):
> #Try to save it with pickle.. works but
> result = pickle.dumps(self.elements)
> #We can't load the data after !
> self.elements = pickle.loads(result)
>
> #If all works good, send a message
> def handler(req):
> req.write( 'ok' )
> return(mod_python.apache.OK)
>
> #We run this class outside any mod_python event
> my_class = a_class()
> <--
>
> And here is the result :
>
> -->
> MOD_PYTHON ERROR
>
> ProcessId: 5104
> Interpreter: 'localhost.localdomain'
>
> ServerName: 'localhost.localdomain'
> DocumentRoot: '/var/www/'
>
> URI: '/~sebastien/test/'
> Location: None
> Directory: '/home/sebastien/public_html/test/'
> Filename: '/home/sebastien/public_html/test/'
> PathInfo: ''
>
> Phase: 'PythonHandler'
> Handler: 'handler'
>
> Traceback (most recent call last):
>
> File "/usr/lib/python2.4/site-packages/mod_python/importer.py", line
> 1537, in HandlerDispatch
> default=default_handler, arg=req, silent=hlist.silent)
>
> File "/usr/lib/python2.4/site-packages/mod_python/importer.py", line
> 1202, in _process_target
> module = import_module(module_name, path=path)
>
> File "/usr/lib/python2.4/site-packages/mod_python/importer.py", line
> 296, in import_module
> log, import_path)
>
> File "/usr/lib/python2.4/site-packages/mod_python/importer.py", line
> 680, in import_module
> execfile(file, module.__dict__)
>
> File "/home/sebastien/public_html/test/handler.py", line 35, in ?
> my_class = a_class()
>
> File "/home/sebastien/public_html/test/handler.py", line 18, in __init__
> self.save()
>
> File "/home/sebastien/public_html/test/handler.py", line 27, in save
> self.elements = pickle.loads(result)
>
> File "pickle.py", line 1394, in loads
> return Unpickler(file).load()
>
> File "pickle.py", line 872, in load
> dispatch[key](self)
>
> File "pickle.py", line 1083, in load_inst
> klass = self.find_class(module, name)
>
> File "pickle.py", line 1138, in find_class
> __import__(module)
>
> ImportError: No module named _mp_e3b5c44c50230d33c470783bc2809f23
>
>
> MODULE CACHE DETAILS
>
> Accessed: Thu Jun 14 22:49:06 2007
> Generation: 3
>
> _mp_e3b5c44c50230d33c470783bc2809f23 {
> FileName: '/home/sebastien/public_html/test/handler.py'
> Instance: 3 [RELOAD]
> Generation: 3 [ERROR]
> Modified: Thu Jun 14 22:48:49 2007
> Imported: Thu Jun 14 22:37:06 2007
> }
> <--
>
> When I launch this program inside a terminal, all works fine, there
> are no error message, so I don't understand what happend..
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mm_cfg_has_not_been_edited_to_set_host_domains/pipermail/mod_python/attachments/20080730/76c75ce5/attachment.html
|