[Zope] get_transaction().commit() does not commit: Zope: OOBTree
definition & creation
Harm_Kirchhoff at mail.digital.co.jp
Harm_Kirchhoff at mail.digital.co.jp
Sun Nov 16 20:07:56 EST 2003
Thank you very much for your comments.
Yes, I shortened the code, because otherwise the mails get too long. This
is a basic accounting db, using Zope, which I intend to make publicly
available once it is stable, so disclosing the code is no problem at all,
just a question of length and this mailing list is already very active.
I researched further, and it seems that it is the question of where you
define the OOBTree.
I naively thought you simply define the entire DB as an OOBTree, but I
realized that you only define sub-branches as OOBTrees and only upon
creation. I made some changes and now it runs. However, I am puzzled by
your comment that an OOBTree does not allow these transactions. How do you
open a db with an OOBTree ???
When I open the file AccDB.fs with a text editor I can see, that my code
must have been executed, because I can see the strings for the nodes !
The new code (again shortened, because the original is still work in
progress and contains a lot of scrap, if you want the full code, because
there is something fundamentally strange, let me know I can mail it
directly.):
(PS: I know that my style is extremely unpythonic, but don't be too
strict, I am only on python since a couple of months)
The main loop:
def test():
db = AccountingDB()
print 'Database file:',db.mountedDB
# create a ledger
r = db.ledger_create('001','2003')
if r[0] == False:
if r[1][0] == 2:
print "The database file does not exist, Will be created new
now!"
db.mount_db(True)
db.unmount_db()
print "DB Created, now creating ledger anew !"
r = db.ledger_create('001','2003')
if r[0] == False : print 'failed miserably ! aborting ...' ;
return
print "Created new DB & ledger, congrats !"
else:
print r
print "Can not find DB file. Aborting ..."
return
# open the ledger
print db.ledger_open('001','2003')
print db.ledger_close()
Produces this output in the shell, provided the db file does not exist:
>>> AccDB.test()
Database file: C:\Documents and Settings\Kirchhoff\My
Documents\Python\AccDB\AccDB.fs
The database file does not exist, Will be created new now!
DB Created, now creating ledger anew !
Created new DB & ledger, congrats !
(True, 'Opened:C:\\Documents and Settings\\Kirchhoff\\My
Documents\\Python\\AccDB\\AccDB.fs')
(True, 'Closed')
The functions,
ledger_create:
Creates a new DB and a basic ledger in dictionary form and closes the
ledger.
ledger_open:
Opens an existing ledger.
ledger_close:
Closes an existing ledger.
I am 100% sure that the code is executed, because all functions perform
basic entry checks and do abort if they can not find a valid ledger
structure in place. On top, the function basic_validation() performs an
extensive validation of the infrastructure, so that the code would abort
with an error message, if the ledgers were not correctly created:
def __init__(self):
# Defines variables to be used throughout the instance, while the
# session is in place.
#
self.mountedDB = 'C:\Documents and Settings\Kirchhoff\My
Documents\Python\AccDB\AccDB.fs'
self.cust_acc = ''
self.fin_yr = ''
self.open = ''
self.maxper = 13
self.periods = ','.join(map(str,range(1,self.maxper+1)))
self.open_per = ''
self.closed_pers = []
self.user = ''
def mount_db(self, flag=False):
""" Mounts the accounting database."""
# Check that my DB exists. This is the default. However, when the
very first ledger is created,
# Zope must create a DB and for this, the check must be skipped.
if flag == False:
r = hkToolBox.Test_File(self.mountedDB,'w')
if r == False:
r = hkToolBox.Test_File(self.mountedDB, 'e')
if r == False :
return(False,[2,'File does not exist'])
else :
return(False,[1,'File can not be opened for writing'])
# Mount DB:
# Note: If you have an error in this section, upon re-run it is
likely
# that the db is still locked and that FileStorage wil fail,
because no connection.close() was executed.
# Solution: End python and restart python.
self.st = FileStorage.FileStorage(self.mountedDB)
self.db = DB(self.st)
self.connection = self.db.open()
self.dbroot = self.connection.root()
#self.dbroot = OOBTree() I found that when you
define
# entire root as
OOBTree on every start
# data is not stored.
return (True,'db mounted:'+ self.mountedDB)
def unmount_db(self):
""" Unmounts the database. This is required to free the locking
that ZODB tracks in its
lock table."""
get_transaction().commit() # commit any changes that may be
pending.
self.connection.close()
self.db.close()
self.st.close()
def ledger_create(self,CstNo,FY):
"""Creates a new ledger for a customer and a new financial
year.""" #Input Validation: CstNo & FY must be strings.
# Input validation:
if type(CstNo) <> str :
return(False,[1000,'CstNo no string'])
if type(FY) <> str :
return(False,[1001,'FY must be string'])
r = self.mount_db()
if r[0] == False :
return(False,r[1])
# Ensure that this account and financial year does not exist:
if self.dbroot.has_key(CstNo) == True :
if self.dbroot[CstNo].has_key(FY) == True :
self.unmount_db() ;
return(False, FY+' exist for '+CstNo)
else : # if CstNo sub-branch does not exist
self.dbroot[CstNo] = OOBTree()
# Only define the OOBTree once, upon
creation.
self._p_changed = 1
get_transaction().commit()
# Since neither this FY or neither this FY nor CstNo do exist,
create base ledger:
# Note: This ledger must pass the basic_validation() !
zero=chr(0)+chr(0)+chr(0)+chr(0)
# Set up basic infrastructure
self.dbroot[CstNo] = { FY :{} }
self.dbroot[CstNo] [FY] = { 'ini' : {} , 'accper' : {} }
self.dbroot[CstNo] [FY] ['ini'] ['lastE'] = zero
self.dbroot[CstNo] [FY] ['ini'] ['lastS'] = zero
self.dbroot[CstNo] [FY] ['ini'] ['locked'] = ''
self.dbroot[CstNo] [FY] ['ini'] ['closed'] = []
self.dbroot[CstNo] [FY] ['ini'] ['open'] = '1'
self.dbroot[CstNo] [FY] ['ini'] ['templ'] = ''
self.dbroot[CstNo] [FY] ['1'] = {}
self.dbroot[CstNo] [FY] ['1'] ['E'] = {}
self.dbroot[CstNo] [FY] ['1'] ['S'] = {}
self.dbroot[CstNo] [FY] ['1'] ['accno'] = {}
self.dbroot[CstNo] [FY] ['1'] ['acba' ] = {}
self._p_changed = 1
get_transaction().commit()
# I recommend always to leave validation here, because it ensures
that both routines
# are always in concordance & will help in future debugging.
r = self.basic_validation(CstNo,FY)
self.unmount_db()
if r[0] == False : return
(False, r[1])
return (True,[0,'ledger created ok'])
def ledger_open(self,CstNo, FY, User='guest'):
"""iniializes the class with basic settings."""
# Initializes the database environment.
# These variables will be used throughout the instance to access
records.
# If this ledger does not yet exist, a new one is created.
# Returns:
# Tuple:(False/True , 'error message if False')
#Input Validation
if type(CstNo) <> str :
return(False,[1000,'CstNo must be string'])
if type(FY) <> str :
return(False,[1001,'FY must be string'])
r = self.mount_db()
if r[0] == False :
return(False,r[1])
# if you need to validate the user (pathword &c.), do it here.
# Verify that DB is not locked. If not, lock it now.
if self.dbroot.has_key(CstNo) == False :
self.unmount_db() ;
return(False, [3,'Customer account does not exist'])
if self.dbroot[CstNo].has_key(FY) == False :
self.unmount_db() ;
return(False, [4,'Financial Year does not exist'])
# Test that this branch (Fin Year of Customer) is not in use &
reserve:
if self.dbroot[CstNo] [FY] ['ini'] ['locked'] <> '' :
return(False,[5,self.dbroot[CstNo] [FY] ['ini'] ['locked']])
self.dbroot[CstNo] [FY] ['ini'] ['locked'] = User
get_transaction().commit()
# Debug: Validate the database:
m=self.basic_validation(CstNo,FY)
if m[0] == False : self.unmount_db() ;
return(False, m[1])
# Set the environment variables for the instance
self.cust_acc = CstNo
self.fin_yr = FY
self.user = User
self.open_per = self.dbroot[self.cust_acc] [self.fin_yr]
['ini'] ['open']
self.closed_pers = self.dbroot[self.cust_acc] [self.fin_yr]
['ini'] ['closed']
# ... happy booking !
return(True,'Opened:' + self.mountedDB)
def ledger_close(self):
"""Closes currently opened ledger & unmounts DB."""
# check that environment variables are proper and that branch is
actually locked.
if self.dbroot.has_key(self.cust_acc) == False :
self.unmount_db() ;
return(False, [3,'Custumer account does not exist'])
if self.dbroot[self.cust_acc].has_key(self.fin_yr) == False :
self.unmount_db() ;
return(False, [4,'Financial Year does not exist'])
# unlock branch
u0 = self.dbroot[self.cust_acc] [self.fin_yr] ['ini'] ['locked']
self.dbroot[self.cust_acc] [self.fin_yr] ['ini'] ['locked'] = ''
self._p_changed = 1
get_transaction().commit()
# unmount DB
self.unmount_db()
# reset all variables.
u1 = self.user
self.__init__()
# just for checking consistency:
if u0 <> u1 :
return(False,[6,'User who closed was not same as opened'])
return(True, 'Closed')
Dieter Maurer <dieter at handshake.de>
2003/11/15 04:50
宛先: Harm_Kirchhoff at mail.digital.co.jp
cc: zope at zope.org
件名: Re: [Zope] get_transaction().commit() does not commit
Harm_Kirchhoff at mail.digital.co.jp wrote at 2003-11-14 19:28 +0900:
> I guess it is another newbie question, but I can not save data to the
DB:
>
> I open the DB like this:
>
> self.st = FileStorage.FileStorage(self.mountedDB)
> self.db = DB(self.st)
> self.connection = self.db.open()
> self.dbroot = self.connection.root()
> self.dbroot = OOBTree()
> return (True,'db mounted:'+ self.mountedDB)
>
> Next I make a number of changes to self.dbroot:
>
> self.dbroot[CstNo] [FY] ['1'] ['E'] = {}
Are you sure, this code is executed?
An "OOBTree" would not allow these operations.
> ...
> When I open again and try verify whether the keys exist, using
> self.dbroot.has_key(CstNo) # for example
> they do not exist.
> Looking at the DB with a text editor to see what is in there, reveals
that
> there is nothing.
> The entire program runs through without any error.
There must be more about which you do not tell us.
Somewhere inside this darkness is something that confuses you.
--
Dieter
More information about the Zope
mailing list