[Modeling-users] Handling Custom Data Types [was: Re: Money and Modeling]
Status: Abandoned
Brought to you by:
sbigaret
From: Sebastien B. <sbi...@us...> - 2003-07-09 10:05:48
|
Yannick Gingras <ygi...@yg...> writes: > On Tuesday 08 July 2003 20:18, Sebastien Bigaret wrote: > > I wrote: > > > [...] BTW, have you looked at the python > > > cookbook or searched for any monetary handling package? I'm quite > > > confident such problems must have been already addressed somewhere, > > > it's probably worth the search. > > > > Instant Google search: > > http://fixedpoint.sourceforge.net/html/lib/module-FixedPoint.html >=20 > Nice ! >=20 > Will Modeling return some fixed points of shoulf I do the trick with > varchars ? Okay, I've thought a little about it and made some experimentations. This is a (yet undocumented) way of handling custom data types, i.e. data types that are not automatically handled by the core. I've made the following changes to test package AuthorBooks to adapt Book's attribute price to fixedPoint: - changed the model so that price is a string/VARCHAR (was: a float/NUMERIC(10,2)), - add _setPrice() and _getPrice() to AuthorBooks.Book (see the unified diff below) Now for the test: (remember to regenerate the DB schema!) >>> from fixedpoint import FixedPoint >>> from AuthorBooks.Book import Book >>> from Modeling.EditingContext import EditingContext >>> ec=3DEditingContext() >>> book=3DBook() >>> book.setTitle('Test FixedPoint') >>> book.setPrice(FixedPoint("3.341")) >>> book.getTitle(), book.getPrice() ('Test FixedPoint', FixedPoint('3.34', 2)) # PRECISION=3D=3D2 in Book.py >>> ec.insert(book) >>> ec.saveChanges() >>> book.getTitle(), book.getPrice() ('Test FixedPoint', FixedPoint('3.34', 2)) Here you can check in you db that it was stored as a varchar, as expected. Start a new python and test the fetch: >>> from fixedpoint import FixedPoint >>> from AuthorBooks.Book import Book >>> from Modeling.EditingContext import EditingContext >>> ec=3DEditingContext() >>> books=3Dec.fetch('Book') >>> books[0].getTitle(), books[0].getPrice() ('Test FixedPoint', FixedPoint('3.34', 2)) As you can see, FixedPoint is now correctly handled by the framework. Nice, isn't it?! Behind the scenes: here you can see the KeyValueCoding in action. The framework *always* accesses the attributes' values with the so-called "private" methods (storedValueForKey(), takeStoredValueForKey()). Look at their documentation, you'll see that they will try to use private setters/getters --such as _setPrice() and _getPrice()-- before the public ones --being getPrice() and setPrice()). So: 1. when the framework is about to save the data, it ends up calling _getprice(), which gently returns the corresponding string, =20=20=20=20 [same for validation before saving: type checking also calls _getPrice() and gets a string, so everything's ok] =20=20=20=20 2. when the framework fetches the data, price() is initialized with _setPrice() which turns the string back to FixedPoint. It's probably what you need here ;) However, attention please: I've never used this in real projects (never needed it), so I cannot guarantee that you won't get any errors at some point. If you choose that way and encounter errors or unexpected behaviour, please report, I'll try to my best to support this. And I'd be interested in success report too ;) -- S=E9bastien. ------------------------------------------------------------------------ Index: Book.py =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/testPackages/Aut= horBooks/Book.py,v retrieving revision 1.4 diff -u -r1.4 Book.py --- Book.py 27 Mar 2003 11:47:57 -0000 1.4 +++ Book.py 9 Jul 2003 09:52:24 -0000 @@ -1,7 +1,9 @@ # Modeling from Modeling.CustomObject import CustomObject from Modeling.Validation import ValidationException +from fixedpoint import FixedPoint =20 +PRECISION=3D2 =20 class Book (CustomObject): """ @@ -61,7 +63,14 @@ "Change the Book / price attribute value" self.willChange() self._price =3D price + self._price.precision=3DPRECISION =20=20=20 + def _setPrice(self, value): + self._price =3D FixedPoint(value, PRECISION) +=20=20=20=20 + def _getPrice(self): + return str(self._price) +=20=20=20=20 def validatePrice(self, value): "Edit this to enforce custom business logic" if 0: # your custom bizlogic Index: model_AuthorBooks.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/testPackages/Aut= horBooks/model_AuthorBooks.xml,v retrieving revision 1.6 diff -u -r1.6 model_AuthorBooks.xml --- model_AuthorBooks.xml 7 May 2003 11:27:10 -0000 1.6 +++ model_AuthorBooks.xml 9 Jul 2003 09:36:23 -0000 @@ -27,7 +27,7 @@ <attribute isClassProperty=3D'1' columnName=3D'title' name=3D'title' i= sRequired=3D'1' precision=3D'0' defaultValue=3D'None' externalType=3D'VARCH= AR' width=3D'40' scale=3D'0' type=3D'string' displayLabel=3D'Title'/> <attribute isClassProperty=3D'1' columnName=3D'id' name=3D'id' isRequi= red=3D'1' precision=3D'0' defaultValue=3D'0' externalType=3D'INT' width=3D'= 0' scale=3D'0' type=3D'int' displayLabel=3D''/> <attribute isClassProperty=3D'0' columnName=3D'FK_WRITER_ID' name=3D'= FK_Writer_Id' isRequired=3D'0' precision=3D'0' defaultValue=3D'None' extern= alType=3D'INTEGER' width=3D'0' scale=3D'0' type=3D'string' displayLabel=3D'= '/> - <attribute isClassProperty=3D'1' columnName=3D'PRICE' name=3D'price' = isRequired=3D'0' precision=3D'10' defaultValue=3D'None' externalType=3D'NUM= ERIC' width=3D'0' scale=3D'2' type=3D'float' displayLabel=3D''/> + <attribute isClassProperty=3D'1' columnName=3D'PRICE' name=3D'price' = isRequired=3D'0' precision=3D'0' defaultValue=3D'None' externalType=3D'VARC= HAR' width=3D'10' scale=3D'0' type=3D'string' displayLabel=3D''/> <relation deleteRule=3D'0' isClassProperty=3D'1' multiplicityUpperBoun= d=3D'1' multiplicityLowerBound=3D'0' destinationEntity=3D'Writer' name=3D'a= uthor' displayLabel=3D'' joinSemantic=3D'0'> <join sourceAttribute=3D'FK_Writer_Id' destinationAttribute=3D'id'/> </relation> ------------------------------------------------------------------------ |