ZODB and Boa

G

Gary

If this is inappropriate here, please advise...

I'm having some difficulty getting ZODB to play nice with Boa.
Specifically, after creating a simple interface with a text field &
btn, I added a python module and imported it into the main (wxFrame)
code:

(python module code)
import ZODB.config
db = ZODB.config.databaseFromURL('calendar.conf')
conn = db.open()
dbroot = conn.root()
dbname = 'calendar_db'
sched = dbroot[dbname]

from persistent import Persistent
#from persistent.list import PersistentList
#from persistent.mapping import PersistentMapping

class Calendr(Persistent):
def __init__(self):
self.date = 0
self.datedata = ()
self.fds = []
self.first = []
self.second = []
self.third = []
self.all = []
self.stats = {}

abc = sched[20050101]
efg = abc.first
print efg
(end code)

When run (from the wxFrame), the textbox value set to 'efg,' an err
msg states that 'first' is not an attribute of Calendr.
When the textbox value is set to str(abc), the err msg states:
<persistent broken __main__.Calendar instance
'\x00\x00\x00\x00\x00\x00\x00\x1c'>

When the python module is run directly (thru Boa), it seems to work
fine, and the print value seen in the code above appears in the Output
section of the Boa Editor frame.

Any direction appreciated.

--
 
D

Diez B. Roggisch

Gary said:
I'm having some difficulty getting ZODB to play nice with Boa.
Specifically, after creating a simple interface with a text field &
btn, I added a python module and imported it into the main (wxFrame)
code:

(python module code)
import ZODB.config
db = ZODB.config.databaseFromURL('calendar.conf')
conn = db.open()
dbroot = conn.root()
dbname = 'calendar_db'
sched = dbroot[dbname]

from persistent import Persistent
#from persistent.list import PersistentList
#from persistent.mapping import PersistentMapping

class Calendr(Persistent):
def __init__(self):
self.date = 0
self.datedata = ()
self.fds = []
self.first = []
self.second = []
self.third = []
self.all = []
self.stats = {}

abc = sched[20050101]
efg = abc.first
print efg
(end code)

When run (from the wxFrame), the textbox value set to 'efg,' an err
msg states that 'first' is not an attribute of Calendr.
When the textbox value is set to str(abc), the err msg states:
<persistent broken __main__.Calendar instance
'\x00\x00\x00\x00\x00\x00\x00\x1c'>

When the python module is run directly (thru Boa), it seems to work
fine, and the print value seen in the code above appears in the Output
section of the Boa Editor frame.

I encountered similar problems when the objects serialized were imported as
members of a certain module - and then, when that module is not found under
that name when deserializing, the object is broken as yours. So make sure
that if your object is of type foo.Bar, when deserializing import foo,
containing Bar.
 
G

Gary

Gary said:
I'm having some difficulty getting ZODB to play nice with Boa.
Specifically, after creating a simple interface with a text field &
btn, I added a python module and imported it into the main (wxFrame)
code:

(python module code)
import ZODB.config
db = ZODB.config.databaseFromURL('calendar.conf')
conn = db.open()
dbroot = conn.root()
dbname = 'calendar_db'
sched = dbroot[dbname]

from persistent import Persistent
#from persistent.list import PersistentList
#from persistent.mapping import PersistentMapping

class Calendr(Persistent):
def __init__(self):
self.date = 0
self.datedata = ()
self.fds = []
self.first = []
self.second = []
self.third = []
self.all = []
self.stats = {}

abc = sched[20050101]
efg = abc.first
print efg
(end code)

When run (from the wxFrame), the textbox value set to 'efg,' an err
msg states that 'first' is not an attribute of Calendr.
When the textbox value is set to str(abc), the err msg states:
<persistent broken __main__.Calendar instance
'\x00\x00\x00\x00\x00\x00\x00\x1c'>

When the python module is run directly (thru Boa), it seems to work
fine, and the print value seen in the code above appears in the Output
section of the Boa Editor frame.

I encountered similar problems when the objects serialized were imported as
members of a certain module - and then, when that module is not found under
that name when deserializing, the object is broken as yours. So make sure
that if your object is of type foo.Bar, when deserializing import foo,
containing Bar.

Thanks for the quick reply.

Excuse my newbiehood/ignorance, I'm not sure I understand your reply.
Would you please elaborate?

When I run the python module stand-alone, or within boa with 'Run
Module,' - no problem. However, when I run it via 'Run Application,'
it first hits this code:

#!/usr/bin/env python
#Boa:App:BoaApp
from wxPython.wx import *

import calFrame1

modules ={'calFrame1': [1, 'Main frame of Application',
'calFrame1.py']}

class BoaApp(wxApp):
def OnInit(self):
wxInitAllImageHandlers()
self.main = calFrame1.create(None)
self.main.Show()
self.SetTopWindow(self.main)
return True

def main():
application = BoaApp(0)
application.MainLoop()

if __name__ == '__main__':
main()
<end code>

....and no cigar.


-Gary
--
 
D

Diez B. Roggisch

Hi,
Excuse my newbiehood/ignorance, I'm not sure I understand your reply.
Would you please elaborate?

I'll try.

From your first post:
As you can see, ZODB tries to instanciate a class Calendar, that is supposed
to be defined in the python file that is executed by the interpreter - thus
resulting in the __name__ == "__main__", and no module-name prefixed to the
class name "Calendar".

But I doubt that Calendar is defined there, in fact your seconds post code
showed there is only some gui-stuff - instead it will be located in some
module, maybe the "calFrame1" you imported, or in module "code" from your
previous post. I assume the latter for now.

Now when you run the code that first created and stored Calendar objects,
you did run it directly, resulting in the fully qualified classname beeing

__main__.Calendar

But now running your app, you want it to be code.Calendar. Unfortunately,
there is no way (or at least not known to me) to alter the class name
after it has been stored.

So this might help: Delete the ZODB FileStorage, and then rerun your
program. It will work.

Then look at the module "code". Don't use it as you do now - its generally
not a good idea to let code be executed in a modules rump when its
imported. Instead, rewrite it like this:

class Calendar:
....

def init():
# do the initialization stuff you did before in the rump here

if __name__ == "__main__":
# if executed directly, reimport ourselves under the desired name, and
then run init
import code
code.init()

That should then make things work in both ways.
 
G

Gary

On Thu, 14 Oct 2004 11:24:41 +0200, "Diez B. Roggisch"

<snip>

Well, Diez, thank you for your patience & help.
I don't understand the mechanism very well, but the solution was to
build and populate the database from inside boa; I'd originally done
so through the python interpreter in a stand-alone module. I put the
following code in the 'Frame' module (the one that contains all the
GUI initialization code, the 'App' module is the one I'd printed out
in the last message):

<start code>
import ZODB.config; import cPickle; import datetime

db = ZODB.config.databaseFromURL('calendar.conf')
conn = db.open()
dbroot = conn.root()
from BTrees.OOBTree import OOBTree # --- Removed when run later
dbname = 'calendar_db'
dbroot[dbname] = OOBTree() # --- Removed when run later
sched = dbroot[dbname] # DB reference variable

from persistent import Persistent
from persistent.list import PersistentList
from persistent.mapping import PersistentMapping

class Calendar(Persistent):
def __init__(self):
self.date = 0
self.datedata = ()
self.fds = []
self.first = []
self.second = []
self.third = []
self.all = []

d=datetime.date; t=datetime.timedelta
start = d(2005,1,1); incr = t(days=1)
fname = 'baseschedule.dat'
f = file(fname)
bs = cPickle.load(f)

for ii in range(1,366):
conv = start.strftime("%Y%m%d")
piz = Calendar()
piz.date = int(conv)
piz.fds = bs.get(ii)[4][0]
piz.first = bs.get(ii)[1][1:]
piz.second = bs.get(ii)[2][1:]
piz.third = bs.get(ii)[3][1:]
piz.all = bs.get(ii)[4]
sched[piz.date] = piz
get_transaction().commit()
del(piz)
start = start + incr

db.close()
<end code>

With that done, I moved the code above - minus the OOBTree lines and
the populating sections - into a module named 'aMod.' I added an
import line, 'from aMod import * to the 'Frame' module, then added a
function to the aMod module:

def foob():
squink = sched[20050509]
return squink.first

I then added this to the Frame module:

def OnButton1Button(self, event):
self.stext.SetValue(str(foob()))
event.Skip()

Now when the application is run, a click on the button finally gives
me the list value that was stored in the database earlier.

I've been working with Python since July, Boa a little later and ZODB
since earlier this week. Notwithstanding occasional detours &
hair-pulling, it still beats Access & Visual Basic by a long shot. : )

Thanks again,
Gary
--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top