modeling-users Mailing List for Object-Relational Bridge for python (Page 37)
Status: Abandoned
Brought to you by:
sbigaret
You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(2) |
Sep
(3) |
Oct
|
Nov
|
Dec
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(19) |
Feb
(55) |
Mar
(54) |
Apr
(48) |
May
(41) |
Jun
(40) |
Jul
(156) |
Aug
(56) |
Sep
(90) |
Oct
(14) |
Nov
(41) |
Dec
(32) |
| 2004 |
Jan
(6) |
Feb
(57) |
Mar
(38) |
Apr
(23) |
May
(3) |
Jun
(40) |
Jul
(39) |
Aug
(82) |
Sep
(31) |
Oct
(14) |
Nov
|
Dec
(9) |
| 2005 |
Jan
|
Feb
(4) |
Mar
(13) |
Apr
|
May
(5) |
Jun
(2) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2006 |
Jan
(1) |
Feb
(1) |
Mar
(9) |
Apr
(1) |
May
|
Jun
(1) |
Jul
(5) |
Aug
|
Sep
(5) |
Oct
(1) |
Nov
|
Dec
|
| 2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
(1) |
Dec
|
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(4) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Mario R. <ma...@ru...> - 2003-04-21 11:14:11
|
On dimanche, avr 20, 2003, at 14:58 Europe/Amsterdam, Sebastien Bigaret wrote: > Mario Ruggier <ma...@ru...> wrote: >> i would like to be able to write and read unicode (as transparently as >> possible) to a text attribute. Postgres/PyPgSQL supports this (see the >> 'Databases' section in http://dalchemy.com/opensource/unicodedoc/ >> -- an article I found very useful). However I have no idea about >> mysql. >> >> It seems that modeling operates in latin-1? Is this true? >> Can I work around this in any way, or configure the framework to >> assume utf-8 as encoding? The problem with latin-1 is that it >> is not a unicode encoding, so even if most of the special characters >> I would need to handle now are latin-1, sooner than later there will >> be problems. > > latin-1? No, I never assumed a particular encoding for strings. It > can be that the framework does not behave correctly because of the > unicode type, but if this happens this is definitely a bug, it was > not > intended. It's me who was assuming a particular encoding, when setting the values ;) > Two kinds of problems may arise: > > 1. the underlying adaptor itself (musqldb,psycopg, etc.) do not handle > uncide strings very well --I've no idea how adapters handle this, > never tried it, PyPgSQL handles it transparently (but internally he encodes anyway to UTF-8), and thus you can directly execute a query unicode string, and he will return results encoded in client_encoding (see article ref above). What I was asking, is can I tell the Framework to set extra parameters such as the client_encoding, when connecting and crating cursors? > 2. mdl assumes that the strings' type is string, not unicode, and some > operations fail. > > I never tried unicode strings, hence I do not have more to say on > that. > > Maybe you could go ahead and try it, and then report? OK: If i try to send a unicode string value where a string is expected, a ValidationException is generated for that attribute. However, as expected, if I take care to encode all string values to utf-8 before sending them to the db via the framework, it all works fine. Filtering of objects also works fine, e.g. if i specify a qual such as ' someAtt=="someUtf8String"'. I guess case-insensitive matches will not work, as Yannick pointed out (thanks!). But, case does not really mean much when applied generically to unicode (the concept of case is not for all languages?). The only issue is that is is a little bit of a pity to have to take care that all string values must be sent, and received as, utf-8 encoded strings. But in fact this is a really small price to pay -- especially if the input means is a utf-8 encoded web form, which thus automatically sends data as utf-8, and wants to receive it in utf-8. mario |
|
From: Mario R. <ma...@ru...> - 2003-04-21 07:55:51
|
Just a minor comment, w.r.t. naming of the generated files/classes.
I feel that:
a) "Base" is probably not the best name extension to use, as it has
a well-known generic meaning, and in addition it says nothing about
the "volatility" of these generated files/classes. Better names would
be something like "Auto" or "Gen" or "mdl" or "pom" or "morfy" ...
b) It is unnecessarily repeated -- what is the point of naming all the
classes in the "Base" sub-package also with "Base"? Wouldn't it be
more convenient to name only the sub-package? E.g.
mortal
|-- Objects
| |-- Article.py
| |-- Auto
| | |-- Article.py
| | |-- Folder.py
| | |-- RssFeed.py
| | |-- __init__.py
| |-- Folder.py
| |-- RssFeed.py
| |-- __init__.py
| |-- model_Mortal.py
| |-- model_Mortal.xml
| `-- setup.py
`-- __init__.py
which implies the import statements in the "working: classes:
==============================================
# Modeling Automatically-generated Objects
import Auto
class Folder(Auto.Folder):
...
==============================================
Regards, mario
> On Sun, Apr 20, 2003 at 06:24:35PM +0200, Sebastien Bigaret wrote:
[snip]
> mortal
> |-- Objects
> | |-- Article.py
> | |-- Base
> | | |-- ArticleBase.py
> | | |-- FolderBase.py
> | | |-- FolderBase.pyc
> | | |-- RssFeedBase.py
> | | |-- __init__.py
> | | `-- __init__.pyc
> | |-- Folder.py
> | |-- Folder.pyc
> | |-- RssFeed.py
> | |-- __init__.py
> | |-- model_Mortal.py
> | |-- model_Mortal.xml
> | `-- setup.py
> `-- __init__.py
[snip]
>
> 2) I look at the code i generated:
> ==============================================
> # Modeling Base Objects
> from Base.FolderBase import FolderBase
>
>
> class Folder(FolderBase):
> """
> Folders are objects ...
> """
>
> def __init__(self):
> "Initializer"
> FolderBase.__init__(self)
> ===============================================
[snip]
|
|
From: <so...@la...> - 2003-04-20 20:43:21
|
On Sun, Apr 20, 2003 at 06:24:35PM +0200, Sebastien Bigaret wrote:
>
> > Next step on this will be to integrate the 'Base' generation-scheme,
> > as discussed earlier on the mailing-list (with a patch proposed by
> > soif).
This is from my first tests. Little things that i don't really
like :
1) As you proposed in the last discussion about this my previous patch do
something like that:
mortal
|-- Objects
| |-- Article.py
| |-- Base
| | |-- ArticleBase.py
| | |-- FolderBase.py
| | |-- FolderBase.pyc
| | |-- RssFeedBase.py
| | |-- __init__.py
| | `-- __init__.pyc
| |-- Folder.py
| |-- Folder.pyc
| |-- RssFeed.py
| |-- __init__.py
| |-- model_Mortal.py
| |-- model_Mortal.xml
| `-- setup.py
`-- __init__.py
as my package name is mortal.Objects, you can see that Base class
are cleary separated from the class you work on.
2) I look at the code i generated:
==============================================
# Modeling Base Objects
from Base.FolderBase import FolderBase
class Folder(FolderBase):
"""
Folders are objects ...
"""
def __init__(self):
"Initializer"
FolderBase.__init__(self)
===============================================
This is from the CVS version
===============================================
from FolderBase import FolderBase
from Modeling.Validation import ValidationException
from mx.DateTime import DateTimeFrom
class Folder(FolderBase):
"""
Folders are objects ...
"""
def __init__(self):
"Initializer"
# Note: if you modify this method, it is a strong requirement that
# every parameter gets a default value, since the framework needs to be
# able to instanciate an object with no parameter at all.
FolderBase.__init__(self)
===============================================
--> from Modeling.Validation import ValidationException
--> from mx.DateTime import DateTimeFrom
twiced imported (in working and in base)
the __init__(self).. have a wrong comment isnt'it ?
this isn't a big trick
>
> Ok, done. If you want to test, please update
>
> scripts/mdl_generate_python_code.py
> ModelMasons/ (whole directory)
>
>
> The old generation scheme is still the default (we can change that for 0.9),
> or with option -C (C for compact)
It should be the defaut in ZModeling too ( I haven't checkout this)
> The new one is accessible w/ the -B option (B for base)
> It generates <className>Base.py as well as <className>.py
>
> As in the 'compact' scheme, files model_<modelName>.py and .xml are
> overwritten. Additionally, '...Base' module are also overwritten.
> (TBD Note: this should be documented within the script's --help)
This sound a good feature. Anyways i don't care about anything in
Base folder w/ my patch
>
> Inheritance:
>
> The following inheritance hierarchy is generated for
> StoreEmployees.Employee/Executive:
>
> EmployeeBase <--- Employee <---- ExecutiveBase <---- Executive
>
>
> I applied the old and new schemes to StoreEmployees and AuthorBooks, with
> success (tests OK). However, here again I'll appreciate if somebody
> interested in the topic could test and double-check with his own project
> (Brad, Soif?)
Hum I don't remember how my patch handle inheritance in fact . and i
don't have a working inheritance here ...
Anyways despite my comments the generated code (from the CVS version)
works fine here.
Thanks
|
|
From: Sebastien B. <sbi...@us...> - 2003-04-20 16:24:40
|
> Next step on this will be to integrate the 'Base' generation-scheme,
> as discussed earlier on the mailing-list (with a patch proposed by
> soif).
Ok, done. If you want to test, please update
scripts/mdl_generate_python_code.py
ModelMasons/ (whole directory)
The old generation scheme is still the default (we can change that for 0.=
9),
or with option -C (C for compact)
The new one is accessible w/ the -B option (B for base)
It generates <className>Base.py as well as <className>.py
As in the 'compact' scheme, files model_<modelName>.py and .xml are
overwritten. Additionally, '...Base' module are also overwritten.
(TBD Note: this should be documented within the script's --help)
Inheritance:
------------
The following inheritance hierarchy is generated for
StoreEmployees.Employee/Executive:
EmployeeBase <--- Employee <---- ExecutiveBase <---- Executive
=20=20
I applied the old and new schemes to StoreEmployees and AuthorBooks, with
success (tests OK). However, here again I'll appreciate if somebody
interested in the topic could test and double-check with his own project
(Brad, Soif?)
Regards,
-- S=E9bastien.
|
|
From: Sebastien B. <sbi...@us...> - 2003-04-20 16:12:18
|
Ok, the refactor of ModelMasons/ModelMason.py and PyModelMason.py is
checked in.
The default behaviour has slightly changed:
- before: the building process stops if the target directory already
exists
- now: the generating process do not stop any more. Rather, it ignores
the files that already exists. The only files that are overwritten
are model_<modelName>.xml and model_<modelName>.py.
Please update the following files:
scripts/mdl_generate_python_scripts.py v1.3
ModelMasons/ModelMason.py v1.6
ModelMasons/PyModelMason.py v1.7
Next step on this will be to integrate the 'Base' generation-scheme,
as discussed earlier on the mailing-list (with a patch proposed by
soif).
I quickly checked that my models are correctly generated from python &
ZModeler, I'll appreciate if someone could double-check.
-- S=E9bastien.
|
|
From: Yannick G. <ygi...@yg...> - 2003-04-20 13:53:11
|
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Sunday 20 April 2003 08:58, Sebastien Bigaret wrote:
> latin-1? No, I never assumed a particular encoding for strings. It
> can be that the framework does not behave correctly because of the
> unicode type, but if this happens this is definitely a bug, it was
> not intended.
We use unicode all the time. The 1st time you create and object, if
you don't pass ASCII only data to an attibute of an object, you have
to explicitly encode it with the encoding of your choice.
We use MySQL which does not support unicode at all. We have do our
encoding explicitly but you may have more luck with a unicode DB like
postgres. Encoding explicitly has a few draw backs, we can't do a
case insensitive search and we can't be sure of the length of the
encoded string before we encode it. You have to plan larger fields in
your model. Three times larger than the intended length is safe in most
situations. Latin-1 to UTF8 is about 1.5 time larger but cyrillic
clip near 2.5. Do you own test with a reliable sample of data, UTF8
may take up to 8 bytes per characters:
print len(u'\u58f7\u58d9\u58bc\u585e\u5859'.encode("utf-8"))
Typing the hex values is boring I made a PyQt app in which I can paste
characters I copied from kcharselect :
#!/usr/bin/python
from autogen.UniToPyGui import UniToPyGui
from qt import *
import sys
class UniToPyDialog(UniToPyGui):
def __init__(self, *args):
UniToPyGui.__init__(self, *args)
self.connect(self.okBtn, SIGNAL("clicked()"), self.convertString)
def convertString(self):
unistr = unicode(self.uniTxt.text())
self.uniSizeTxt.setText(str(len(unistr)))
pystr = repr(unistr)
self.pyTxt.setText(pystr)
self.pySizeTxt.setText(str(len(pystr)))
utfstr = unistr.encode("utf-8")
self.utfTxt.setText(utfstr)
self.utfSizeTxt.setText(str(len(utfstr)))
if __name__ == "__main__":
qapp = QApplication(sys.argv)
dialog = UniToPyDialog()
qapp.setMainWidget(dialog)
dialog.show()
qapp.exec_loop()
# The END !
All you need is a UniToPyGui form with a OK button, an a few text edits.
- --
Yannick Gingras
Coder for OBB : Onymous Barrelled Baneberry
http://OpenBeatBox.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)
iD8DBQE+oqZCrhy5Fqn/MRARAqeBAJ0ZaDCwUEKpNSITQZI8gRhj3F38/QCcCO5l
N2l/G7zy4NUhhXk6CzFreyc=
=u0lD
-----END PGP SIGNATURE-----
|
|
From: Yannick G. <ygi...@yg...> - 2003-04-20 13:26:27
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Sunday 20 April 2003 09:05, Sebastien Bigaret wrote: > Last addition: I remember Yannick Gingras saying that it can be > useful to be able to comment on a model -- 1.0 will add a comment > attribute in Model, Entity, Attribute and Relationship. Woohoo ! : D - -- Yannick Gingras Coder for OBB : Obese Barehanded Bse http://OpenBeatBox.org -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE+op/+rhy5Fqn/MRARAp6rAJ0Wm28MuQaLkWDarJvq4GeBBBBNdwCfVXCL IVjAJYJ4kRsWUk8Mk4ngRus= =NPQH -----END PGP SIGNATURE----- |
|
From: Sebastien B. <sbi...@us...> - 2003-04-20 13:14:32
|
Mario Ruggier <ma...@ru...> wrote: > I think the partial dispose os what the refaultObject() is about. >=20 > Ah, terminology! >=20 > >> - EditingContext: include refaultObject() > >> status: proposed a patch on the ml > >> https://sf.net/mailarchive/forum.php?thread_id=3D1884326&forum_id=3D10= 674 > >> > >> Has anyone used this for real? > > I don't :( >=20 > > We talk about the partial dispose too, but i think we will work on > > that for 1.0 Right: refaultObject() is definitely the first step towards "partial dispose", in fact it is a major part of the forthcoming ability for an EditingContext to hold <n> fully initialized objects at most, when possible. I do not want to include 'refaultObject()' in 0.9 unless some testing is done in the meantime. I'm pretty sure myself that I wont have the time for this. -- S=E9bastien. |
|
From: Sebastien B. <sbi...@us...> - 2003-04-20 13:05:29
|
> To the list of things to do for 0.9 i'd only like to add: > - consistency check of the UserGuide for the new features of 0.9 > - add 1-web-page example, using perhaps the StoreEmployees model. I agree with you and soif, this is important. > An issue that probably should be resolved before 0.9 is the name of > the framework. This implies a lot, though... 1.0 hopefully ;) > The new feature of having the possibility to define a Model directly > in python is for another release. Planned in the 0.9 series (after the question by soif asking for a long-term planning, I'll comment on the 0.9 series later) Last addition: I remember Yannick Gingras saying that it can be useful to be able to comment on a model -- 1.0 will add a comment attribute in Model, Entity, Attribute and Relationship. -- S=E9bastien. |
|
From: Sebastien B. <sbi...@us...> - 2003-04-20 12:58:22
|
Hi, Mario Ruggier <ma...@ru...> wrote: > i would like to be able to write and read unicode (as transparently as > possible) to a text attribute. Postgres/PyPgSQL supports this (see the > 'Databases' section in http://dalchemy.com/opensource/unicodedoc/ > -- an article I found very useful). However I have no idea about mysql. >=20 > It seems that modeling operates in latin-1? Is this true? > Can I work around this in any way, or configure the framework to > assume utf-8 as encoding? The problem with latin-1 is that it > is not a unicode encoding, so even if most of the special characters > I would need to handle now are latin-1, sooner than later there will > be problems. latin-1? No, I never assumed a particular encoding for strings. It can be that the framework does not behave correctly because of the unicode type, but if this happens this is definitely a bug, it was not intended. Two kinds of problems may arise: 1. the underlying adaptor itself (musqldb,psycopg, etc.) do not handle uncide strings very well --I've no idea how adapters handle this, never tried it, 2. mdl assumes that the strings' type is string, not unicode, and some operations fail. I never tried unicode strings, hence I do not have more to say on that. Maybe you could go ahead and try it, and then report? -- S=E9bastien. PS: Oh, maybe you thought latin-1 because of the 'latin-1' in the model? That one in the model only specifies how the xml file is produced, and it has nothing to do with the framework runtime. |
|
From: Mario R. <ma...@ru...> - 2003-04-20 12:33:30
|
I think the partial dispose os what the refaultObject() is about. Ah, terminology! >> - EditingContext: include refaultObject() >> status: proposed a patch on the ml >> https://sf.net/mailarchive/forum.php?thread_id=1884326&forum_id=10674 >> >> Has anyone used this for real? > I don't :( > We talk about the partial dispose too, but i think we will work on > that for 1.0 |
|
From: Mario R. <ma...@ru...> - 2003-04-20 12:25:55
|
Hello, i would like to be able to write and read unicode (as transparently as possible) to a text attribute. Postgres/PyPgSQL supports this (see the 'Databases' section in http://dalchemy.com/opensource/unicodedoc/ -- an article I found very useful). However I have no idea about mysql. It seems that modeling operates in latin-1? Is this true? Can I work around this in any way, or configure the framework to assume utf-8 as encoding? The problem with latin-1 is that it is not a unicode encoding, so even if most of the special characters I would need to handle now are latin-1, sooner than later there will be problems. Regards, mario |
|
From: <so...@la...> - 2003-04-20 12:25:04
|
On Sun, Apr 20, 2003 at 02:12:40PM +0200, Mario Ruggier wrote: > Welcome back Sebastien! > > To the list of things to do for 0.9 i'd only like to add: > - consistency check of the UserGuide for the new features of 0.9 Yeap this is important i think > - add 1-web-page example, using perhaps the StoreEmployees model. This should be on the first page > An issue that probably should be resolved before 0.9 is the name of > the framework. This implies a lot, though... This should be for 1.0 no ? > The new feature of having the possibility to define a Model directly > in python is for another release. /Enjoy :) |
|
From: <so...@la...> - 2003-04-20 12:16:55
|
On Sat, Apr 19, 2003 at 06:35:51PM +0200, Sebastien Bigaret wrote: > > Hi all, > > I wish to end with the everlasting wait for 0.9 and release it monday > april, 28th. > > The steps that I think need to be fulfilled until then are: > > - Fix bugs: #710817, #710913 > https://sourceforge.net/tracker/?group_id=58935&atid=489335 I've bugfixed #710817 in my previous patch . > - Possibly fix bug #711817, or change the documentation I hope you will find time to fix that :) I'm waiting for that since a long time :) > - ModelMasons: > > + refactor the package - status: done on my HD, needs to be checked-in > > I'd like someone to double check that there is no remaining bug > when this is checked-in, so I'll be grateful if someone could find > some time next week, after it's committed to cvs, to check on his > own project(s) that the new scheme is working right. > > + propose an alternate scheme for python-code generation: i.e. with > base classes <EntityName>Base, as previously discussed on the > list. > > Status: almost done (cf. patch proposed by Jerome, april, 27th) > needs to be integrated and committed > https://sourceforge.net/mailarchive/forum.php?thread_id=1888241&forum_id=10674 I will wait until you comit this to the CVS. send a mail when it's done. I will check this as soon as possible but i will be off next week (Tuesday -> Saturday) > - EditingContext: include refaultObject() > status: proposed a patch on the ml > https://sf.net/mailarchive/forum.php?thread_id=1884326&forum_id=10674 > > Has anyone used this for real? I don't :( > > I know we were supposed to freeze features until 0.9 final, but I'm > convinced that the few added things can be useful for others. > > Please comment and tell if you think I missed something, I was > offline for quite a time and I could have easily forgotten one point > or another. We talk about the partial dispose too, but i think we will work on that for 1.0 Could you please tell us about your release plan (for long time) ? Enjoy :) -- PS for Sebastien : May we talk in real life when are you free ? |
|
From: Mario R. <ma...@ru...> - 2003-04-20 12:12:44
|
Welcome back Sebastien! To the list of things to do for 0.9 i'd only like to add: - consistency check of the UserGuide for the new features of 0.9 - add 1-web-page example, using perhaps the StoreEmployees model. An issue that probably should be resolved before 0.9 is the name of the framework. This implies a lot, though... The new feature of having the possibility to define a Model directly in python is for another release. Regards, mario |
|
From: Sebastien B. <sbi...@us...> - 2003-04-19 17:31:00
|
Yannick Gingras <ygi...@yg...> writes: > On Saturday 19 April 2003 12:35, Sebastien Bigaret wrote: > > Please comment and tell if you think I missed something, I was > > offline for quite a time and I could have easily forgotten one point > > or another. >=20 > Is XML-Model "compilation" for 0.9 or just for sometimes later ? Definitely: yes; the script is almost finished, based on the one sent on the list earlier, at: https://sourceforge.net/mailarchive/forum.php?thread_id=3D1683824&forum_id= =3D10674 Thanks for reminding me of it! -- S=E9bastien. |
|
From: Yannick G. <ygi...@yg...> - 2003-04-19 16:41:19
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Saturday 19 April 2003 12:35, Sebastien Bigaret wrote: > Please comment and tell if you think I missed something, I was > offline for quite a time and I could have easily forgotten one point > or another. Is XML-Model "compilation" for 0.9 or just for sometimes later ? - -- Yannick Gingras Coder for OBB : Ominous Brittle Baby-sitter http://OpenBeatBox.org -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE+oXwqrhy5Fqn/MRARAu/dAJ42nNAc39x2f73F1viB+BJWcyT8jACcC32T BAVrdkHPOlApsUQPry7KzRA= =66w2 -----END PGP SIGNATURE----- |
|
From: Sebastien B. <sbi...@us...> - 2003-04-19 16:36:00
|
Hi all,
I wish to end with the everlasting wait for 0.9 and release it monday
april, 28th.
The steps that I think need to be fulfilled until then are:
- Fix bugs: #710817, #710913
https://sourceforge.net/tracker/?group_id=3D58935&atid=3D4893=
35
- Possibly fix bug #711817, or change the documentation
- ModelMasons:
+ refactor the package - status: done on my HD, needs to be checked-in
I'd like someone to double check that there is no remaining bug
when this is checked-in, so I'll be grateful if someone could find
some time next week, after it's committed to cvs, to check on his
own project(s) that the new scheme is working right.
+ propose an alternate scheme for python-code generation: i.e. with
base classes <EntityName>Base, as previously discussed on the
list.
Status: almost done (cf. patch proposed by Jerome, april, 27th)
needs to be integrated and committed
https://sourceforge.net/mailarchive/forum.php?thread_id=3D1888241&forum_id=
=3D10674
- EditingContext: include refaultObject()
status: proposed a patch on the ml
https://sf.net/mailarchive/forum.php?thread_id=3D1884326&forum_id=3D10674
Has anyone used this for real?
- regarding bug #614261
https://sourceforge.net/mailarchive/forum.php?thread_id=3D1795493&forum_id=
=3D10674
Can someone using MySQL confirm that this eliminates that kind of
errors? I'll close the bug item, then.
I know we were supposed to freeze features until 0.9 final, but I'm
convinced that the few added things can be useful for others.
Please comment and tell if you think I missed something, I was
offline for quite a time and I could have easily forgotten one point
or another.
Cheers,
-- S=E9bastien.
|
|
From: <so...@la...> - 2003-03-27 21:38:52
|
On Thu, Mar 27, 2003 at 12:18:06PM +0100, Sebastien Bigaret wrote: > > soif> I think i will modify the bricks to handle this, during the week i > soif> hope. > > Now I agree that this could/should be handled at generation time, > because this problem is a generic one. We should be able to offer the > users an example of such an architecture, as soif suggested it, with a > different python "brick". Soif, if you're going to study this maybe we > could discuss that a bit --I'll suggest however not to modify the > existing python brick, but to derive a new one for this purpose. For > example, the following code-generation process could be implemented: > > - take an existing model (no 'Generation', no 'Base'), say AuthorBooks, > > - modify it to generate AuthorBooks.Base.AuthorBase and BookBase, > where package AuthorBooks.Base is where live all the files that will > be overriden unconditionally when re-generating the model (including > the model) --we could simply use the existing python brick for that > purpose. > > - Last, generate the modules/subclasses Author & Book in package > AuthorBooks if and only if the modules do not already exists. > > > What do you think? Hum join you will find - PyModelMason patched: - fix bug #710817 that I discover 2 weeks ago but forget to report - added the building of Package.Base folder - integrated the inher_module.tmpl - module.tmpl patched: Added 'Base' where it should be - inher_module.tmpl This is the result of the model_AuthorBooks.xml tree /tmp/AuthorBooks/ /tmp/AuthorBooks/ |-- Base | |-- BookBase.py | |-- WriterBase.py | `-- __init__.py |-- Book.py |-- DEPENDENCIES.txt |-- INSTALL.txt |-- README.txt |-- TODO.txt |-- VERSION.txt |-- Writer.py |-- __init__.py |-- model_AuthorBooks.py |-- model_AuthorBooks.xml `-- setup.py Short note: I haven't created a new Mason/bricks because 1) This really need some rewrites (PyModelMason.py), perhaps I should wait for that. 2) I really think this should be the default behaviour 3) I dont' have so much time, and i lost some with the 2 bugs reported this afternoon. Please test and report bugs /Enjoy |
|
From: Brad B. <br...@bb...> - 2003-03-27 14:19:31
|
On 03/27/03 12:18, Sebastien Bigaret wrote:
[wholesale snip]
> > 4. Change an Entity's description so that it can have, perhaps both a
> > baseclass *and* class attribute, where the baseclass attribute is the
> > one that will get autogenerated and the class attribute is the only
> > that I will code myself, overriding and extending the baseclass's
> > methods as necessary.
> >
> > >From the point of view of the person that designed this framework,
> > what do you think of each of these options? Have I missed any?
>
>
> Following Mario's arguments, I don't think exposing a base class in the
> description of entities is a good idea; but that's a detail however,
> because the general idea of generating only baseclasses is the good one,
> and the one I use and recommend. Here are the details of the technique I
> currently use:
>
> Suppose we design a model AuthorBooks with entities Author and Books.
>
> 1. design your model, name it 'AuthorBooksGeneration'
>
> 2. design your entities, name them AuthorBase and BookBase
>
> 3. generate the code: you get the package with the classes, plus
> model_AuthorBooksGeneration.xml
>
> 4. in the same package, write class Author in module Author.py:
>
> ------------------------------------------------------------------------
> from AuthorBase import AuthorBase
> class Author(AuthorBase):
> def __init__(self):
> AuthorBase.__init__(self)
> #...
> ------------------------------------------------------------------------
>
> Same for Book
>
> 5. drop the compile_model_AuthorBooks.py included at the end of the
> message in the package and execute it (adapt it to your own needs)
> It produces a new model, AuthorBooks, pointing to the subclasses
> Author and Book.
>
> 6. Modify __init__.py so that the loaded model is AuthorBooks, not
> AuthorBooksGeneration
>
>
> Now you have classes Author and Book that won't be overriden when
> generating your classes again, using the original model
> AuthorBooksGeneration. The only thing you'll have to do after each
> re-generation is step 5. & 6. --obviously you still need to backup
> __init__.py if you added code to it.
Indeed. This seems like a reasonable and conveniently
backward-compatible solution. I'm pretty lazy though, so I'd like to
invest some time with others developing the framework's core to
automate this process and make it transparent to the user.
> *PLEASE* backup your work before giving it a try, I've no time by now to
> double-check that there is no risk at all and I do not want you to lose
> your work just because I forgot some points in the procedure...
>
> This technique demonstrates that the model is really used at runtime
> to find out which classes it should use, here: not the base classes,
> but the subclasses. This is somehow a derivation of the 1st FAQ entry
> (section 2.6).
I agree that it's probably better to just Do The Right Thing, rather
than have the user care about having to define a bunch of baseclasses
in the model to avoid code destruction.
[snip]
> Further comments on this:
> soif> I think i will modify the bricks to handle this, during the week i
> soif> hope.
>
> Now I agree that this could/should be handled at generation time,
> because this problem is a generic one. We should be able to offer the
> users an example of such an architecture, as soif suggested it, with a
> different python "brick". Soif, if you're going to study this maybe we
> could discuss that a bit --I'll suggest however not to modify the
> existing python brick, but to derive a new one for this purpose. For
> example, the following code-generation process could be implemented:
>
> - take an existing model (no 'Generation', no 'Base'), say AuthorBooks,
>
> - modify it to generate AuthorBooks.Base.AuthorBase and BookBase,
> where package AuthorBooks.Base is where live all the files that will
> be overriden unconditionally when re-generating the model (including
> the model) --we could simply use the existing python brick for that
> purpose.
>
> - Last, generate the modules/subclasses Author & Book in package
> AuthorBooks if and only if the modules do not already exists.
>
>
> What do you think?
Works for me. :)
--
Brad Bollenbach
BBnet.ca
|
|
From: Yannick G. <ygi...@yg...> - 2003-03-27 13:31:28
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Thursday 27 March 2003 07:48, Sebastien Bigaret wrote: > Yannick, this may be of some interest to you as well: as far as I > remember you declare your PK as class properties, too. Yes, I used to make a ugly hack :=20 snapshot =3D obj.snapshot() snapshot.update(self.__ec.globalIDForObject(obj).keyValues()) I debuged quite =E0 long time to find that saveChanges() did not set the value into the object... Thanks for the info ! : ) - --=20 Yannick Gingras Coder for OBB : Optically Bookable Barbados http://OpenBeatBox.org -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE+gv0srhy5Fqn/MRARArMnAKCAc3KNgNuX3pTRcB4RcULkmB1z7ACcC6uh /up0+hY1E+gvvCwvuSSuws8=3D =3DAvNq -----END PGP SIGNATURE----- |
|
From: Sebastien B. <sbi...@us...> - 2003-03-27 12:48:44
|
Sebastien Bigaret <sbi...@us...> wrote: > [snip] > > >=20 > > > You are using getId() (returning article._id) instead of getID() > > > (returning the PK value stored in its GlobalID) ! > > >=20 > > >=20 > > > However, we have a bug here: Article's PK did not get its value. > >=20 > >=20 > soif> Yeah you got it :)=20 > soif> If don't use the id as classProperty as said in the doc, and use=20 > soif> the getID() helper sent before on the list it works well :)=20 >=20 > I included a small patch at the end of the message to solve this issue > --I'll make the unittest tomorrow and will correct this on the cvs > rep. Now article._id should get its value as expected after > ec.saveChanges(), if it's set as a class property. Done, you'll find it on cvs, EditingContext v1.22. Yannick, this may be of some interest to you as well: as far as I remember you declare your PK as class properties, too. -- S=E9bastien. |
|
From: Sebastien B. <sbi...@us...> - 2003-03-27 11:18:22
|
Hi Brad & all,
Mario and soif did already comment, so I get directly to the point
Thanks Brad for raising the problem, it definitely should be answered!
Brad Bollenbach <br...@bb...> wrote:
> Now, onto my question:
>=20
> How do I customize the business logic validation routines without my
> customizations getting blown away the next time I autogenerate the
> Python package (e.g. when I decide two months down the line that the
> app needs to be extended and five more tables need to be added)?
As it was previously said, this is an interesting topic that should be
addressed and documented quickly. Most people face this problem once
they begin to develop real projects.
Mario> I also have the same question, and so I suggest that a recommendation
Mario> of how this is best handled should be added to the users guide...
At least a recommendation, yes! I'll also expose another solution at
the end of the message: we could propose more than a recommendation: a
new generation scheme making life easier in these situations. However
in the meantime, I agree this should be integrated in the User's
Guide. I'll try to be as precise as possible, so that we can perhaps
use it as a raw material for a coming section in the doc.
>=20
> I've read through many of your unit tests, and a few relevant bits of
> the code and come up with what I see being the four realistic options:
>=20
> 1. The obvious one: add code directly to autogenerated Python
> code. The problem here though, is that it's difficult to do the whole
> backup-and-merge dance when I autogenerate again in the future. It's
> also tedious to take the other route of only exporting the XML model
> every time, and maintaining the classes (and/or adding new ones, if
> applicable) to keep up with it.
It's the obvious one, for which cvs can help you a lot (wrt merging the
changes). This was the technique I once used, however this quickly
becomes tedious, indeed.
Soif also said that:
soif> 2) How would you stay update w/ the modeling if you change the
soif> "bricks" (template used to generate code)
I must make it clear here that the templates/bricks used to generate the
code only contains the basics for the classes to be integrated into the
framework (i.e.: entityname() plus getters & setters calling
willRead()/willChange()). A real big change in the templates/generated
code would imply that the framework changed the way it integrates the
classes. This may happen in the future --I'm thinking ZODB's Persistent
class-- but this would be advertised and some migration scheme would be
proposed at that time.
Until then, changes in the templates will not impact existing code.
soif> But i think this is a piece of the tool. I think you can use this
soif> "bricks" to generate some custom class
Sure, but the framework needs refactoring as far as the code-generation
is concerned. The way the ModelMasons are built is unclear and indeed
ugly, the API is unclear as well, badly documented, and part of it is
even useless. This is on the TODO list, with no ETA.
> 2. Write an adoption utility function, e.g. def adoptByClass(adopter,
> entities) that will iterate over a list of entities (e.g. those
> fetched from an editing context) and map them to the class specified
> as the "adopter". The "adopter" could be a class that I've created
> that inherits from one of the auto-generated classes and overrides its
> validation methods with my custom logic. It's good because I can
> autogenerate again and again, but it's bad because then I'm always
> making calls to adoptByClass.
>=20
> 3. Manually validate (e.g. using MySQLdb directly). This would ignore
> a significant piece of functionality that's already been created as
> part of the Modeling framework, so this isn't reasonable.
I don't like these two approaches and wouldn't recommend them, for the
same reasons you and soif gave.
> 4. Change an Entity's description so that it can have, perhaps both a
> baseclass *and* class attribute, where the baseclass attribute is the
> one that will get autogenerated and the class attribute is the only
> that I will code myself, overriding and extending the baseclass's
> methods as necessary.
>=20
> >From the point of view of the person that designed this framework,
> what do you think of each of these options? Have I missed any?
Following Mario's arguments, I don't think exposing a base class in the
description of entities is a good idea; but that's a detail however,
because the general idea of generating only baseclasses is the good one,
and the one I use and recommend. Here are the details of the technique I
currently use:
Suppose we design a model AuthorBooks with entities Author and Books.
1. design your model, name it 'AuthorBooksGeneration'
2. design your entities, name them AuthorBase and BookBase
3. generate the code: you get the package with the classes, plus
model_AuthorBooksGeneration.xml
4. in the same package, write class Author in module Author.py:
------------------------------------------------------------------------
from AuthorBase import AuthorBase
class Author(AuthorBase):
def __init__(self):
AuthorBase.__init__(self)
#...
------------------------------------------------------------------------
Same for Book
5. drop the compile_model_AuthorBooks.py included at the end of the
message in the package and execute it (adapt it to your own needs)
It produces a new model, AuthorBooks, pointing to the subclasses
Author and Book.
6. Modify __init__.py so that the loaded model is AuthorBooks, not
AuthorBooksGeneration
Now you have classes Author and Book that won't be overriden when
generating your classes again, using the original model
AuthorBooksGeneration. The only thing you'll have to do after each
re-generation is step 5. & 6. --obviously you still need to backup
__init__.py if you added code to it.
=20=20=20=20=20
*PLEASE* backup your work before giving it a try, I've no time by now to
double-check that there is no risk at all and I do not want you to lose
your work just because I forgot some points in the procedure...
This technique demonstrates that the model is really used at runtime
to find out which classes it should use, here: not the base classes,
but the subclasses. This is somehow a derivation of the 1st FAQ entry
(section 2.6).
I hope this is clear enough; hopefully you'll find that this approach
can be an answer to your needs. Mario's and soif's comments, just like
yours, were exactly pointing to this direction.
Further comments on this:
soif> I think i will modify the bricks to handle this, during the week i
soif> hope.
Now I agree that this could/should be handled at generation time,
because this problem is a generic one. We should be able to offer the
users an example of such an architecture, as soif suggested it, with a
different python "brick". Soif, if you're going to study this maybe we
could discuss that a bit --I'll suggest however not to modify the
existing python brick, but to derive a new one for this purpose. For
example, the following code-generation process could be implemented:
- take an existing model (no 'Generation', no 'Base'), say AuthorBooks,
- modify it to generate AuthorBooks.Base.AuthorBase and BookBase,
where package AuthorBooks.Base is where live all the files that will
be overriden unconditionally when re-generating the model (including
the model) --we could simply use the existing python brick for that
purpose.
- Last, generate the modules/subclasses Author & Book in package
AuthorBooks if and only if the modules do not already exists.
What do you think?
-- S=E9bastien.
------------------------------------------------------------------------
#! /usr/bin/env python
"""
compile_model_AuthorBooks
``Compile'' an xml_model into two python modules, model_<modelName>.py and
model_<modelName>_pickled.py:
- model_<model_name>.py: contains the whole xml-file in a single module
attribute: model_src
=20=20
- model_<modelName>_pickled.py: the second one contains a single attrib=
ute
as well: model_pickle, which is a raw string to be loaded by
cPickle.loads()
=20=20=20=20=20=20
Specific processing added:
This script is dedicated to the model stored in
'model_AuthorBooksGeneration.xml'
The model within the xml file is loaded and changed (see fixModel()) th=
en
written back to the filesystem, with the name 'AuthorBooks', under the
three following forms:
- xml file 'model_AuthorBooks.xml',
- python file 'model_AuthorBooks.py',
- python file 'model_AuthorBooks_pickle.py'
Written by: Sebastien Bigaret
"""
import sys, getopt
def loadModel(xmlFilePath):
"""
Loads the model stored in the xml file
"""
from Modeling import ModelSet
ms=3DModelSet.ModelSet()
ms.addModelFromXML({'file': xmlFilePath})
model=3Dms.models()[0]
model._modelSet=3DNone
return model
def fixModel(model):
"""
Sets the model's name to 'AuthorBooks'; removes 'Base' from the
entities' module name and class name.
Returns: nothing
"""
model.setName('AuthorBooks')
for e in model.entities():
name=3De.moduleName()
if name[-4:]=3D=3D'Base':
e.setModuleName(name[:-4]) # remove Base
name=3De.className()
if name[-4:]=3D=3D'Base':
e.setClassName(name[:-4]) # remove Base
def write_xml_model(model):
"""
Writes the model into the xml-file 'model_<modelName>.xml' ; creates a
python module (file: 'model_<modelName>.py') and dumps the content of the
xml-file in a string attribute named 'model_src'
"""
# write xml file
xml_file_path=3D'model_%s.xml'%model.name()
model.saveModelAsXMLFile(xml_file_path)
# write python file
xml=3Dopen(xml_file_path, 'r')
file=3Dopen('model_%s.py'%model.name(), 'w')
file.write('model_src=3D"""')
s=3Dxml.readline()
while s!=3D'':
file.write(s)
s=3Dxml.readline()
file.write('"""\n')
xml.close()
file.close()
=20=20
def write_pickled_model(model):
"""
Creates a python module (file: model_<modelName>_pickle.py) and dumps a
pickled version of the supplied model in module's attribute 'model_pickle=
'.
"""
import cPickle
file=3Dopen('model_%s_pickle.py'%model.name(), 'w')
file.write('model_pickle=3Dr"""')
pickled=3DcPickle.dump(model, file)
file.write('"""\n')
file.close()
def usage(prgName, exitStatus=3DNone):
print """%s <model.xml>
``Compile'' an xml_model into two python modules, model_<modelName>.py and
model_<modelName>_pickled.py.
- model_<model_name>.py: contains the whole xml-file in a single module
attribute: model_src
- model_<modelName>_pickled.py: the second one contains a single attribute
as well: model_pickle, which is a raw string to be loaded by
cPickle.loads()
NB: this adaptation is dedicated to the processing of
'model_AuthorBooksGeneration.xml'. See code and its documentation for
details.
Options
-------
-h Prints this message
""" % prgName
if exitStatus:
sys.exit(exitStatus)
def main(argv):
me=3Dargv[0]
try:
options, args =3D getopt.getopt(argv[1:], 'h')
except getopt.GetoptError,msg:
usage(me, 1)
=20=20=20=20
verbose=3D0
=20=20
for k, v in options:
if k=3D=3D'-h': usage(me, 0)
if len(args)!=3D1:
usage(me,1)
=20=20=20=20
model=3DloadModel(args[0])
fixModel(model)
write_xml_model(model)
write_pickled_model(model)
=20
if __name__ =3D=3D "__main__":
main(sys.argv)
------------------------------------------------------------------------
|
|
From: <so...@la...> - 2003-03-27 01:18:37
|
On Wed, Mar 26, 2003 at 05:10:15PM -0600, Brad Bollenbach wrote:
> Hello,
Hy ;)=20
>=20
> How do I customize the business logic validation routines without my
> customizations getting blown away the next time I autogenerate the
> Python package (e.g. when I decide two months down the line that the
> app needs to be extended and five more tables need to be added)?
Hum, i want to point you that this problem isn't validation centric.
Look at this example:
--------------------------------------------------
class RssFeed(CustomObject):
__implements__ =3D CustomObject.__implements__
=20
def __init__(self):
self._title =3D 'unknow feed'
self._url =3D ''
---------------------------------------------------
As you can see i have a entity RssFeed with an url and a title,
not really a big deal. I want this object to handle the rss from=20
a website. I think the best way to go that is to have a getFeed()
method on the RssFeed object. So I just added something like that
to the generated class=20
....
def getFeed(self):
if not getattr(self,'_feed',None):
self._feed =3D rssparser.parse(self.getUrl())
return self._feed
....
So this kind of wrapping against ModelingObject can't be generated.
=20
> I've read through many of your unit tests, and a few relevant bits of
> the code and come up with what I see being the four realistic options:
>=20
> 1. The obvious one: add code directly to autogenerated Python
> code. The problem here though, is that it's difficult to do the whole
> backup-and-merge dance when I autogenerate again in the future. It's
> also tedious to take the other route of only exporting the XML model
> every time, and maintaining the classes (and/or adding new ones, if
> applicable) to keep up with it.
This is really a bad idea, cause=20
1) You can't handle all the variant you will need to build real app=20
2) How would you stay update w/ the modeling if you change the
"bricks" (template used to generate code)
But i think this is a piece of the tool. I think you can use this
"bricks" to generate some custom class
> 2. Write an adoption utility function, e.g. def adoptByClass(adopter,
> entities) that will iterate over a list of entities (e.g. those
> fetched from an editing context) and map them to the class specified
> as the "adopter". The "adopter" could be a class that I've created
> that inherits from one of the auto-generated classes and overrides its
> validation methods with my custom logic. It's good because I can
> autogenerate again and again, but it's bad because then I'm always
> making calls to adoptByClass.
This is perhaps a good idea, but i don't feel it really pythonic=20
Perhaps using interface will fix that . (Hum .. I don't feel interface
pythonic too in fact :))
> 3. Manually validate (e.g. using MySQLdb directly). This would ignore
> a significant piece of functionality that's already been created as
> part of the Modeling framework, so this isn't reasonable.
This won't work, because=20
1) you will have to handle specials db connections for that (=3D> overhea=
d)
2) my experience with SQL in modeling say that this is a bad habbit cause=
you
will have some big trouble with object carring some values in the edit=
ing
context, and not in the DB (remember that you can't store a object=20
ec.saveChanges() if one object isn't valid. I think S=E9bastian will=20
say the same.=20
Another trick, always keep in mind how the modeling works while
working on the model. Sometimes, building the model as you should
do in OO, or even in SQL way isn't a good choice.=20
Let take a example, think about a Folder/Article mapping, and for=20
statistics reasons we need to count the number of Article for a object
--------------------------------------------------------
In OO you will find something like this
Folder:
- name(string)
- articles(list)=20
Article:
- name(string)
- text(string)
- parent =3D folder
so counting the number of articles in a folder :=20
len(folder.articles())=20
--------------------------------------------------------
SQL =20
Folder:
- id=20
- name=20
Article:
- name
- text
- FK_FOLDER
so count will to something like that :
SELECT count(+1) as total from Article WHERE FK_FOLDER =3D ....=20
--------------------------------------------------------
So now in the modeling you will have a mix of this too methods.
If you use the OO model, counting articles in a folder by a=20
len( folder.articles()) will fetch all the articles in the EC=20
and that really can be a CPU waste.=20
Using ec.objectsCountWithFetchSpecification(fetchSpec) is a bit=20
like SQL method, but this can force you to have a strange API=20
in your code (read not working on object directly)=20
Perhaps in modeling i will do something like this:
Folder:
- id=20
- name
- number of article
Article:
...=20
=20
This is perhaps not the best example, but I hope you will
understand my meanings.
=20
> 4. Change an Entity's description so that it can have, perhaps both a
> baseclass *and* class attribute, where the baseclass attribute is the
> one that will get autogenerated and the class attribute is the only
> that I will code myself, overriding and extending the baseclass's
> methods as necessary.
The last, but not the least. I really think this is the best way to=20
solve the problem. This remember me how Corba (OmnyORB for example)=20
solve this kind of problem.=20
I think this *should* be handle by the bricks by default in fact.=20
Something like this:
Article_mdl.py=20
--------------------------------------------------------
# generated code never use this directly=20
class Article_mdl(CustomObject):
def __init__(self):
.....
def entityName(self):
return 'Article'
....=20
Article.py=20
--------------------------------------------------------
from Article_mdl import Article_mdl
class Article(Article_mdl):=20
=20
def __init__(self):
Article_mdl.__init__(self):
... my code go here ...
I think i will modify the bricks to handle this, during the week i
hope.=20
Bye Bye :)
I hope you understand my awfull english :)
|
|
From: Mario R. <ma...@ru...> - 2003-03-26 23:48:34
|
Hi there, > How do I customize the business logic validation routines without my > customizations getting blown away the next time I autogenerate the > Python package (e.g. when I decide two months down the line that the > app needs to be extended and five more tables need to be added)? I also have the same question, and so I suggest that a recommendation of how this is best handled should be added to the users guide... > I've read through many of your unit tests, and a few relevant bits of > the code and come up with what I see being the four realistic options: > > 1. The obvious one: add code directly to autogenerated Python > code. The problem here though, is that it's difficult to do the whole > backup-and-merge dance when I autogenerate again in the future. It's > also tedious to take the other route of only exporting the XML model > every time, and maintaining the classes (and/or adding new ones, if > applicable) to keep up with it. > > 2. Write an adoption utility function, e.g. def adoptByClass(adopter, > entities) that will iterate over a list of entities (e.g. those > fetched from an editing context) and map them to the class specified > as the "adopter". The "adopter" could be a class that I've created > that inherits from one of the auto-generated classes and overrides its > validation methods with my custom logic. It's good because I can > autogenerate again and again, but it's bad because then I'm always > making calls to adoptByClass. > > 3. Manually validate (e.g. using MySQLdb directly). This would ignore > a significant piece of functionality that's already been created as > part of the Modeling framework, so this isn't reasonable. > > 4. Change an Entity's description so that it can have, perhaps both a > baseclass *and* class attribute, where the baseclass attribute is the > one that will get autogenerated and the class attribute is the only > that I will code myself, overriding and extending the baseclass's > methods as necessary. I feel this (4) would be the better way to go. However, I would suggest _not_ to expose baseclass of the Entity, i.e. each Entity will have a private basecalss that is regenerated each time. The declared class will be generated if it does not exist (or if overwrite is specified), but is not overwritten otherwise. Simpler, instead of inventing private baseclass names for declared classes, just have a private "sub-package" to the declared package, e.g. _mdl. And in that package have the always-regenerated base classes -- using the same class names declared in the model. mario > -- > Brad Bollenbach > BBnet.ca > |