modeling-users Mailing List for Object-Relational Bridge for python (Page 20)
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: Sebastien B. <sbi...@us...> - 2003-10-27 12:54:26
|
Hi Vladimir, Vladimir <vla...@gu...> wrote: > Hi to everyone! > I'm new to Modeling so I'll need lot of help.... > I was looking for a tool in Zope envirenment, which should be able to use > complex queries on two or more tables in a database. Modeling seems > interesting and so I decided to try it. > Sebastien helped me to install it on windows: >=20=09 > http://modeling.sourceforge.net/download/ModelingCore-0.9-pre-15.win32.exe > http://modeling.sourceforge.net/download/NotificationFramework-0.6.win32.= exe > But now I have this problem: How to make it working in Zope environment? > Unfortunately the Modeling installation wizard can not find the Zope's > python installation and by default installs it in other python installati= on > directory. For the MDL-core, you should copy the lib/python2.1/site-packages/Modeling into your Zope installation, in lib/python2.1/site-packages/ also. For the tools, such as the ZModelizationTool, download and untar the archive, and move the directories ZModelizationTool/ and ZEditingContextSessioning/ into Zope's Products directory (lib/python/Products/). In case this does not work, it would help a lot if you could send the error messages written by Zope. Now, could you elaborate on what you intend to do w/ Zope & the MDL? For the moment being, the ZModeler and the ZEditingContextSessioning are the only products available for Zope. This means in particular that you won't get a running product out-of-the-box to query your database, based on the model ; you'll need to design your own products for that. We can discuss this if you want to. -- S=E9bastien. |
From: Vladimir <vla...@gu...> - 2003-10-25 12:57:19
|
Hi to everyone! I'm new to Modeling so I'll need lot of help.... I was looking for a tool in Zope envirenment, which should be able to use complex queries on two or more tables in a database. Modeling seems interesting and so I decided to try it. Sebastien helped me to install it on windows: http://modeling.sourceforge.net/download/ModelingCore-0.9-pre-15.win32.exe http://modeling.sourceforge.net/download/NotificationFramework-0.6.win32.exe But now I have this problem: How to make it working in Zope environment? Unfortunately the Modeling installation wizard can not find the Zope's python installation and by default installs it in other python installation directory. Best regards, Vladimir |
From: Sebastien B. <sbi...@us...> - 2003-10-22 18:14:41
|
Hi, Federico Heinz <fh...@vi...> wrote: > On Sat, 2003-10-04 at 11:35, Sebastien Bigaret wrote: > > Prerequisite (at least for me:) > > * define a sample model, one root entity A, two sub-entities B and > > C, and at least one sub-entity D for B (we need a sub-sub-entity to > > make sure that the support for vertical mapping will support an > > inheritance tree of any depth). Given this sample model, define: > > - the derived db-schema, > > - SQL statements for selecting, inserting, updating and deleting all > > those 4 entities. >=20 > Well, I've done these, please find them attached. I extended the > StoreEmployee model to add a special kind of SalesClerk, the > AreaSupervisor who gets a commission on the area's sales. I'm providing > the pymodel, the SQL schema as Modiling creates it today, the vertical > mapping schema, and the examples. As you might expect, there are no big > surprises in any of these... Thanks a lot! Unfortunately I probably won't be able to study this in detail in the next two or three weeks; I'm currently fighting against a medical problem, nothing serious, but kind of tiring and I won't probably find the energy to concentrate on that until the surgery... but if I do I'll drop a line or two here of course ;) Sorry for the delay, and again, thanks for the examples. -- S=E9bastien. |
From: Federico H. <fh...@vi...> - 2003-10-20 22:36:11
|
Sébastien, On Sat, 2003-10-04 at 11:35, Sebastien Bigaret wrote: > Prerequisite (at least for me:) > * define a sample model, one root entity A, two sub-entities B and > C, and at least one sub-entity D for B (we need a sub-sub-entity to > make sure that the support for vertical mapping will support an > inheritance tree of any depth). Given this sample model, define: > - the derived db-schema, > - SQL statements for selecting, inserting, updating and deleting all > those 4 entities. Well, I've done these, please find them attached. I extended the StoreEmployee model to add a special kind of SalesClerk, the AreaSupervisor who gets a commission on the area's sales. I'm providing the pymodel, the SQL schema as Modiling creates it today, the vertical mapping schema, and the examples. As you might expect, there are no big surprises in any of these... > * have PyModels (and xml, but we can start w/o xml) support flattened > attributes and relationships. I think xml the important part would be to get the back-end to accept dotted-path notation, then pymodel and XML would be just a matter of them allowing the notation. > BTW this is how /I/ think the model would be designed: > - define root entity A, > - define sub-entity B w/ parent=A, > - in sub-entity B, define a to-one rel. 'toA' to the parent; this > relationship will join B's PK to A's PK (and will probably not > be a class property), > - in sub-entity B, flatten every properties of A > (def.='toA.<attrName>' or 'toA.<relName>') I think this relationship should be implicit, i.e. if the user has already stated that B is a subclass of A, no explicit declaration of the relationship should be required. > --> this is for a single level of inheritance. Now it's not clear to > me at all how this should be done when 2+ levels of inheritance > are involved. Should a sub-entity flatten properties from its > direct parent only, or should it flatten its parents > non-flattened properties, then its parent's parent non-flattened > properties, etc. ? That will probably be clearer when we'll have > examples on how this is best done at the SQL level. In keeping with the spirit of the current XML schema, it seems to me that it would be best to flatten every attribute in every class. In such a case, AreaSupervisor's the store_area attribute would be flattened as "toSales_Clerk.store_area" and the first_name would be flattened as "toSales_Clerk.toEmployee.first_name". Actually, if we didn't have multiple nuisance (sorry: inheritance), we could automatically call this relationship "super". > We also need to make sure that defining a PyModel w/ vertical > mapping will be painless. That must not be that difficult, in fact > it should be sufficient to i. detect that a sub-entity has a > different externalName() (db-table's name) than its parent, > ii. automatically append the necessary items in the sub-entity > (toOne rel. to parent, flattened properties). Hmmm... not sure about this one... currently, sub-entities have different externalName()s than their parents (after all, they are different tables!). I can't quite make up my mind whether the choice between vertical and horizontal mapping should be a global option of the model, or decided on an entity-by-entity basis (thus allowing for both kinds of mapping to coexist in the same schema). Fede |
From: Mario R. <ma...@ru...> - 2003-10-20 00:10:39
|
hi, I am following up on these tests with a separate installation of python 2.2.2, to avoid the bug new.instancemethod() in 2.2. The basic tests are successful, but have not had time to experiment with these with my own models. The log for the tests is below. These are running on OS X 10.2.8. Cheers, mario % /sw/bin/python2.2 ./run.py ---------------------------------------------------------------------- Ran 107 tests in 7.663s OK % /sw/bin/python2.2 ./test_EditingContext_Global.py -c -r % /sw/bin/python2.2 ./test_EditingContext_Global.py -c ---------------------------------------------------------------------- Ran 39 tests in 12.770s OK % /sw/bin/python2.2 ./test_EditingContext_Global.py -m -r % /sw/bin/python2.2 ./test_EditingContext_Global.py -m ---------------------------------------------------------------------- Ran 39 tests in 14.627s OK % /sw/bin/python2.2 ./test_EditingContext_Global.py -M -r % /sw/bin/python2.2 ./test_EditingContext_Global.py -M ---------------------------------------------------------------------- Ran 39 tests in 14.023s OK % /sw/bin/python2.2 ./test_EditingContext_Global_Inheritance.py -c ---------------------------------------------------------------------- Ran 22 tests in 17.953s OK % /sw/bin/python2.2 ./test_EditingContext_Global_Inheritance.py -m ---------------------------------------------------------------------- Ran 22 tests in 16.697s OK % /sw/bin/python2.2 ./test_EditingContext_Global_Inheritance.py -M ---------------------------------------------------------------------- Ran 22 tests in 16.719s OK % /sw/bin/python2.2 ./test_EditingContext_ParentChild.py -c ---------------------------------------------------------------------- Ran 16 tests in 6.994s OK % /sw/bin/python2.2 ./test_EditingContext_ParentChild.py -m Ran 16 tests in 5.789s OK % /sw/bin/python2.2 ./test_EditingContext_ParentChild.py -M ---------------------------------------------------------------------- Ran 16 tests in 7.132s OK % > Hi all, > > I've just uploaded a new patch for the new dynamic feature > https://sf.net/tracker/=20 > index.php?func=3Ddetail&aid=3D814055&group_id=3D58935&atid=3D489337 > > Changes are: > > - run.py testsuite has been fixed and should pass now, > - dynamic.build() can now also add properties to the generated > classes (when parameter define_properties is true). Hence tests > have a new option -C ("classic" build w/ properties) > > - toMany relationships are initialized with () (empty tuple) =20 > instead > of [] (empty list). > > Note on properties: while attributes are well handled, they can be > dangerous for relationships when they are stored as list instead of > tuples. For example, in the current version, author.books=3D[] is > correctly handled, but author.books.append(new_book) isn't: it does = not > mark the object as modified, since author.willChange() is not > called. For those who know zodb, the ZODB.Persistent class has the = same > problem in this case, and _p_changed should be manually set to 1. > > It is not clear to me whether a special proxy-class (deriving from > types.ListType) should be specially designed for handling > modifications of lists for relationships. BTW if you store > relationships as tuples, not lists, then the problem disappears. > > -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-10-05 15:52:58
|
Hi all, I've just uploaded a new patch for the new dynamic feature https://sf.net/tracker/index.php?func=3Ddetail&aid=3D814055&group_id=3D5893= 5&atid=3D489337 Changes are: - run.py testsuite has been fixed and should pass now, - dynamic.build() can now also add properties to the generated classes (when parameter define_properties is true). Hence tests have a new option -C ("classic" build w/ properties) - toMany relationships are initialized with () (empty tuple) instead of [] (empty list). Note on properties: while attributes are well handled, they can be dangerous for relationships when they are stored as list instead of tuples. For example, in the current version, author.books=3D[] is correctly handled, but author.books.append(new_book) isn't: it does not mark the object as modified, since author.willChange() is not called. For those who know zodb, the ZODB.Persistent class has the same problem in this case, and _p_changed should be manually set to 1. It is not clear to me whether a special proxy-class (deriving from types.ListType) should be specially designed for handling modifications of lists for relationships. BTW if you store relationships as tuples, not lists, then the problem disappears. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-10-05 13:10:21
|
Hi, Mario Ruggier <ma...@ru...> wrote: > sorry i did not do this earlier, but i finally managed to give some time > to it. I did as instructed, installing NF 0.6, and the dynamic patch over > the latest installation of the framework, and ran thru the tests as instr= ucted. > I am testing with a Postgresql server. The log of each test is below. > Note there is also a problem with the general test run.py, which I am > placing first... True, the tests/run.py testsuite was not updated and fails. I'll soon send an update for that. > The following tests have been run on an OSX box, python 2.2=20 > ((#1, 07/14/02, 23:25:09) [GCC Apple cpp-precomp 6.14] on=20 > darwin), with Modeling 0.9-pre-15 plus this patch. [...] > % python ./test_EditingContext_Global.py -r -c > [Model.searchModel] Trying ./pymodel_AuthorBooks.py > Traceback (most recent call last): [...] > ".../Modeling/dynamic.py", line 39, in instance_method > meth=3Dnew.instancemethod(func, None, aClass) > TypeError: instancemethod() argument 3 must be class, not type I think you need to upgrade your python version. There is a bug in 2.2 final, fixed from 2.2.1c1, that makes new.instancemethod() fail for new style classes. See: http://sf.net/tracker/index.php?func=3Ddetail&aid=3D503091&group_id=3D547= 0&atid=3D105470 http://www.python.org/2.2.2/NEWS.txt > Anyway, I am not sure I understand all the benefits of this intriguing > new feature, but does this also mean (in particular in option 3 (metaclas= s) > that one can just manually define "CustomObject" classes by specifying > only the custom python code for that class, and never have to worry > about merging with the regenerated modules after model changes? The first reason to make this is that various people asked if there was an alternative to code generation; this demonstrates that we're not tightly bound to code-generation. In fact, this also makes it clearer what requirements need to be fulfilled for CustomObject classes --this will eventually enhance the user's guide too. And yes, this means that you can: 1. directly experiment your models without the code-generation phase, 2. design your classes so that they inherit from the generated modules or use the metaclass; you'll put there any other methods, such as validation methods, and in this case, __init__() and attributes'/ relationships' setters and getters will be automatically in sync with the model --no need to update the source anymore. > Also, why 3 ways? Experimental? Will you pick what is the better of > the 3, and stick with that one? The answer to your last question is still not clear to me. Now on the three ways: - "classic" [-c / dynamic.build()]: because we're supporting py2.1, we need the generation of classic-style classes. Now if you use this w/ py2.2, you'll get new-style classes just because CustomObject is a new-style class. In fact, this dynamic.build() is really equivalent to what you get when generating the code. - metaclass [-M, -m / dynamic.build_with_metaclass()]: this is an alternate method, using metaclass ;) Last, the difference between -M and -m is just properties; this could also be done with the "classic" build. I realized that most people prefer to write book.title=3D"my title" rather than book.setTitle("mytitle"), that's why I added properties. It's also not clear whether the metaclass way is appropriate. You can make your own idea by e.g. reading those two articles (referenced some time ago by the excellent daily-python http://www.pythonware.com/daily): "Metaclasses are evil" by Hans Nowak http://zephyrfalcon.org/weblog/arch_d7_2003_09_06.html#e337 and the sequel: "Metaclasses, reprise" http://zephyrfalcon.org/weblog/arch_d7_2003_09_13.html#e342 This is my first metaclass, so it's highly possible that I fall into the experimenting-and-learning category ;) -- S=E9bastien. |
From: Mario R. <ma...@ru...> - 2003-10-04 22:32:07
|
[please disregard earlier email from me on this subject] Hi. sorry i did not do this earlier, but i finally managed to give some time to it. I ran the tests after installing NF 0.6, and the dynamic patch over the latest installation of the framework, with python 2.2 (stock apple compilation) and running on OSX 10.2.6. I am testing with a Postgresql server (but never gets this far). > I've just submitted patch #814055 at: > https://sf.net/tracker/ > index.php?func=detail&aid=814055&group_id=58935&atid=489337 I have added the log of each test to the issue above. Note there is also a problem with the general test run.py, the log of which is also added. Anyway, I am not sure I understand all the benefits of this intriguing new feature, but does this also mean, in particular in option 3 (metaclass) that one can just manually define "CustomObject" classes by specifying only the custom python code for that class, and never have to worry about merging with the regenerated modules after model changes? Also, why 3 ways of doing it? Experimental? Will you pick what is the better of the 3, and stick with that one? Cheers, mario |
From: Mario R. <ma...@ru...> - 2003-10-04 14:49:01
|
forgot to say that this is running on OSX On Samedi, oct 4, 2003, at 16:45 Europe/Zurich, Mario Ruggier wrote: > sorry i did not do this earlier, but i finally managed to give some > time > to it. I did as instructed, installing NF 0.6, and the dynamic patch > over > the latest installation of the framework, and ran thru the tests as > instructed. > I am testing with a Postgresql server. The log of each test is below. > Note there is also a problem with the general test run.py, which I am > placing first... |
From: Sebastien B. <sbi...@us...> - 2003-10-04 14:35:40
|
Hi, Sorry that I announced the plan for earlier, but I couldn't find the time for it. Looks like I never learn from those time constraints :/ > > because I considered a bit slower than horizontal: with 'nb' classes and > > subclasses, [...] I never tried it --but my opinion has no real > > weight here, remember I'm really not good at sql: that was one of the > > motivation for writing the code :) >=20 > Doh! And I was looking up at you for enlightenment! :-) Yeah, well, you know, if I was a SQL guru I probably wouldn't have need the framework so badly ;) Okay, back to it: here is the 1st draft of a plan to support vertical mapping. Prerequisite (at least for me:) ------------ * define a sample model, one root entity A, two sub-entities B and C, and at least one sub-entity D for B (we need a sub-sub-entity to make sure that the support for vertical mapping will support an inheritance tree of any depth). Given this sample model, define: - the derived db-schema, - SQL statements for selecting, inserting, updating and deleting all those 4 entities. Note: we cannot simply reuse as-is one of the test models AuthorBooks or StoreEmployees, since they involve only one level of inheritance, at most. Code ---- This is what come to my mind by now. We need to: * have PyModels (and xml, but we can start w/o xml) support flattened attributes and relationships. A flattened property is basically a path/dotted notation, such as 'toPerson.name' (stored in an attribute 'definition' of Attribute and Relationship). In the core, both Attribute and FlattenedRelationship are almost ready to store this in models at runtime (I say almost, because it's never been used so it is possible that bugs remain in them) --see methods isFlattened(), definition(). I've a look at them and it seems that the xml support is already almost (if not fully) done. ...Re-reading this, I realize that these 2 classes need to be refactored. The framework will need to know flattened attributes' and relationships' properties from the parent (such as a string's width, a relationship's cardinality, etc.), and this is not supported at all. That's not that bad, both classes need a bit of refactor anyway (yes, they'ere rather old, and pretty ugly if you look at their code). BTW this is how /I/ think the model would be designed: - define root entity A, - define sub-entity B w/ parent=3DA, - in sub-entity B, define a to-one rel. 'toA' to the parent; this relationship will join B's PK to A's PK (and will probably not be a class property), - in sub-entity B, flatten every properties of A (def.=3D'toA.<attrName>' or 'toA.<relName>') --> this is for a single level of inheritance. Now it's not clear to me at all how this should be done when 2+ levels of inheritance are involved. Should a sub-entity flatten properties from its direct parent only, or should it flatten its parents non-flattened properties, then its parent's parent non-flattened properties, etc. ? That will probably be clearer when we'll have examples on how this is best done at the SQL level. We also need to make sure that defining a PyModel w/ vertical mapping will be painless. That must not be that difficult, in fact it should be sufficient to i. detect that a sub-entity has a different externalName() (db-table's name) than its parent, ii. automatically append the necessary items in the sub-entity (toOne rel. to parent, flattened properties). * Have SQLExpression.py detect and generate SQL statements for vertical mapping. This is the biggest part of it, in fact, and probably not the most trivial --the main problem is in fact that SQLExpression's internals are not very well documented, I've a few notes on paper that I should probably put somewhere. I don't not have them at hand though, still need to look for them --or rewrite them. * Write tests for selects, inserts, updates and deletes, * Release the code! -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-10-04 13:07:45
|
Hi, Ernesto Revilla <er...@si...> wrote: > Hi, >=20 > I've installed modeling 0.9-pre15, with sqlite (2.8.6) >=20 > when I create the schema with mdl_generate_DB_schema.py -c then I get out= put with no semicolons (;) separating the SQL commands, and this is not und= erstood by sqlite. >=20 > I modified line 99 of the script (mdl_generate_DB_schema.py) to include a= semicolon: > str+=3D'%s;\n'%sqlExpr.statement() >=20 > now I can do a: > mdl_generate_DB_schema.py -c -C mymodel.py >schema.sql > sqlite mymodel.sqlite < schema.py >=20 > Directly creating the schema (not specifying the -c option) worked correc= tly. Okay, your RFE #812708 has been addressed, see the patch attached to: https://sf.net/tracker/index.php?func=3Ddetail&aid=3D812708&group_id=3D5893= 5&atid=3D489338 (the patch was checked-in the cvs main trunk for mdl_generate_DB_schema.py rev1.8) Note that this has been added to the script itself, not to the core (in DatabaseAdaptors/): it seems a common habit to cursor.execute() SQL statements that do not end with ';', even though this is in the SQL standard. There's an another reason why I do not want that the framework appends semicolons to the sql statements: it gives the impression that statements can be concatenated and executed in a single call to cursor.execute(). But that's not the case, and worse: some python db-frontends simply ignores all but the last statement, while others actually return the result for each statements. This will be in the next release. Note that the old behaviour can still be obtained by supplying an empty string to the new option -e/--end-with. Last note, when things like these change from a version to another, I now always append a line in the file MIGRATION in the root directory. This is a good habit to keep an eye on this file before installing a new version. Cheers, -- S=E9bastien. |
From: Yannick G. <yan...@sa...> - 2003-10-01 14:19:36
|
=2D----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On September 29, 2003 06:20 pm, SoaF-BSD wrote: > > As I said some time ago, we use Datadesigner [1] to make our XML model > > and than we pass it to a DOM transformation tool to have a Modeling > > friendly document. > > Perhaps you can provide this tool ? add this to the CVS .. this could be > great. no ? Sure ! I already posted it some time ago but it didn't seems to generate a lot of interests. Since it's more a convenient internal tool for us than a generic model converter it's a bit tainted by our usage of the framework : public keys are public (we serialize them to cross a XML-RPC bridge), only to-many relations and their inverse are merged and a few points like that. It might be better to swith to a XSLT transform instead. Anyway, if it can help someone, I'm willing to make it more generic. #!/usr/bin/python # Copyright (C) 2003 Savoir-faire Linux <in...@sa...> # by Yannick Gingras <yan...@sa...> # This is dd2pm. # dd2pm is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # dd2pm is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with Open Beat Box; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U= SA """dd2pm.py : Datadesigner to Python Modeling convertion tool. """ from xml.dom.minidom import parseString from xml.dom.ext import PrettyPrint from xml import xpath from xml.xpath import Evaluate import xml import sys DOC_SKEL =3D """<?xml version=3D'1.0' encoding=3D'iso-8859-1'?> <model name= =3D'' />""" DEF_DB =3D "MySQL" DEF_NEEDED_ENTITIES =3D [] DEF_CONNECTION =3D {} DD_PM_TYPE_MAP =3D {"bool": "int", "integer": "int", "int": "int", "varchar": "string", "numeric": "string", "real": "float", "float": "float", "time": "DateTime", "char": "string", "text": "string", "date": "DateTime"} DD_PM_EXT_TYPE_MAP =3D {"tinyint": "int", "smallint": "int", "decimal": "numeric"} def getSourceDom(filename): return parseString(open(filename).read()) def createDoc(): return parseString(DOC_SKEL) class ModelingDDImporter: """Convert a Data Designer shema to PyModeling Model""" def __init__(self, srcDoc, targetDoc, onlyNeededEnts=3D0): """both srcDoc and targetDoc are DOM compliant instances""" self.srcDoc =3D srcDoc self.destDoc =3D targetDoc self.onlyNeededEnts =3D onlyNeededEnts def startConvertion(self): self.model =3D self.destDoc.getElementsByTagName("model")[0] self.project =3D self.srcDoc.getElementsByTagName("project")[0] self.addModelDefAttrs() self.convPrjAttrs() self.extractPrjEntities() self.mutateEntities() self.extractRelations() self.mutateRelations() def addModelDefAttrs(self): self.model.setAttribute("adaptorName", DEF_DB) self.model.setAttribute("connectionDictionary", str(DEF_CONNECTION)) def convPrjAttrs(self): name =3D self.project.getAttribute("name") =20 self.model.setAttribute("name", name) self.model.setAttribute("packageName", name) def extractPrjEntities(self): entitiesNode =3D self.srcDoc.getElementsByTagName("entities")[0] self.prjEntities =3D entitiesNode.getElementsByTagName("entity") def extractRelations(self): relationsNode =3D self.srcDoc.getElementsByTagName("relations")[0] self.relations =3D relationsNode.getElementsByTagName("relation") def mutateEntities(self): for entity in self.prjEntities: needed =3D 1 if self.onlyNeededEnts: if entity.getAttribute("name") not in DEF_NEEDED_ENTITIES: needed =3D 0 if needed: newEntity =3D self.destDoc.createElement('entity') self.model.appendChild(newEntity) self.mutateEntity(entity, newEntity) def mutateRelations(self): for relation in self.relations: needed =3D 1 if self.onlyNeededEnts: parent =3D Evaluate("./parent/text()", relation)[0].nodeVal= ue if parent not in DEF_NEEDED_ENTITIES: needed =3D 0 if needed: newRelation =3D self.destDoc.createElement('relation') self.mutateRelation(relation, newRelation) def getModelEntityWithName(self, name): modelEntities =3D self.model.getElementsByTagName("entity") =20 for modelEntity in modelEntities: if modelEntity.getAttribute("name") =3D=3D name: return modelEntity =20 return None =20 def mutateEntity(self, sourceEntity, destEntity): # mutate names=20 mapping =3D {"name": ["moduleName", "className", "name"], "pname": ["externalName"]} for mapEntry in mapping.items(): val =3D sourceEntity.getAttribute(mapEntry[0]) for attrName in mapEntry[1]: destEntity.setAttribute(attrName, val) # set defaults defaults =3D self.makeDefaults(isReadOnly =3D'0', isAbstract =3D '0', typeName =3D '', parentEntity =3D '') for attrName, val in defaults.items(): destEntity.setAttribute(attrName, val) # mutate misc attrs self.mutateEntAttrs(sourceEntity, destEntity) def mutateEntAttrs(self, sourceEntity, destEntity): entAttrsNode =3D sourceEntity.getElementsByTagName("attributes")[0] entAttrs =3D entAttrsNode.getElementsByTagName("attribute") for entAttr in entAttrs: newEntAttr =3D self.destDoc.createElement("attribute") destEntity.appendChild(newEntAttr) self.mutateEntAttr(entAttr, newEntAttr) def mutateEntAttr(self, sourceEntAttr, destEntAttr): # mutate name name =3D sourceEntAttr.getAttribute("name") destEntAttr.setAttribute("name", name) pname =3D sourceEntAttr.getAttribute("pname") destEntAttr.setAttribute("columnName", pname) # set defaults defaults =3D self.makeDefaults( isClassProperty =3D '1', width =3D '0', isRequired =3D '0', precision =3D '0', defaultValue =3D 'None', scale =3D '0', displayLabel =3D "") for attrName, val in defaults.items(): destEntAttr.setAttribute(attrName, val) # mutate real values mapping =3D {"type": "externalType", "length": "width"} for node in sourceEntAttr.childNodes: if node.nodeType =3D=3D node.ELEMENT_NODE: tagName =3D node.tagName try: value =3D node.firstChild.nodeValue except AttributeError: value =3D "" self.mutateEntAttrType(tagName, value, sourceEntAttr, destEntAttr) def strToBool(self, str): if str =3D=3D "true": return 1 elif str =3D=3D "false": return 0 else: raise Exception("String '%s' cannot be converted to bool" % str) def mutateEntAttrType(self, tagName, value, sourceEntAttr, destEntAttr): if tagName =3D=3D "type": if DD_PM_EXT_TYPE_MAP.has_key(value): value =3D DD_PM_EXT_TYPE_MAP[value] destEntAttr.setAttribute("externalType", value) destEntAttr.setAttribute("type", DD_PM_TYPE_MAP[value]) elif tagName =3D=3D "nullable": destEntAttr.setAttribute("isRequired", str(not self.strToBool(value))) elif tagName =3D=3D "unique": pass elif tagName =3D=3D "primarykey": if self.strToBool(value): newElem =3D self.destDoc.createElement("primaryKey") newElem.setAttribute("attributeName", destEntAttr.getAttribute("name")) destEntAttr.parentNode.appendChild(newElem) destEntAttr.setAttribute("isRequired", '1') destEntAttr.setAttribute("defaultValue", '0') destEntAttr.setAttribute("isClassProperty", '1') elif tagName =3D=3D "foreignkey": if self.strToBool(value): destEntAttr.setAttribute("isClassProperty", '0') elif tagName =3D=3D "isarray": pass elif tagName =3D=3D "imported": pass elif tagName =3D=3D "description": pass elif tagName =3D=3D "default": destEntAttr.setAttribute("defaultValue", value) elif tagName =3D=3D "length": # tricky, converted to width only if there is no precision if sourceEntAttr.getElementsByTagName("decimals"): # use precision destEntAttr.setAttribute("precision", value) else: # use width destEntAttr.setAttribute("width", value) elif tagName =3D=3D "decimals": destEntAttr.setAttribute("scale", value) else: raise Exception("Unknowed node type : %s" % tagName) def mutateRelation(self, sourceRelation, destRelation): # set defaults defaults =3D self.makeDefaults(deleteRule=3D'nullify', isClassProperty=3D'1', multiplicityUpperBound=3D'-1', multiplicityLowerBound=3D'0', displayLabel=3D'', joinSemantic=3D'0') for attrName, value in defaults.items(): destRelation.setAttribute(attrName, value) type =3D xpath.Evaluate("./type/text()", sourceRelation)[0].nodeVal= ue if type =3D=3D "ident": pass # keep the defaults elif type =3D=3D "inform": # reverse relation of a to-many destRelation.setAttribute("multiplicityUpperBound", "1") destRelation.setAttribute("multiplicityLowerBound", "0") else: raise Exception("Can't handle relation type : '%s'" % type) =20 # append relation to master entity parentElem =3D sourceRelation.getElementsByTagName("parent")[0] fromEntity =3D parentElem.firstChild.nodeValue self.getModelEntityWithName(fromEntity).appendChild(destRelation) # set the receiver childElem =3D sourceRelation.getElementsByTagName("child")[0] toEntity =3D childElem.firstChild.nodeValue destRelation.setAttribute("destinationEntity", toEntity) destRelation.setAttribute("name", sourceRelation.getAttribute("name= ")) relAttrsNode =3D sourceRelation.getElementsByTagName("relationattrs= ")[0] bindingNode =3D relAttrsNode.getElementsByTagName("attributebind")[= 0] fromAttr =3D bindingNode.getAttribute("parent") toAttr =3D bindingNode.getAttribute("child") joinElem =3D self.destDoc.createElement("join") joinElem.setAttribute("sourceAttribute", fromAttr) joinElem.setAttribute("destinationAttribute", toAttr) destRelation.appendChild(joinElem) =20 =20 def makeDefaults(self, **kwargs): return kwargs if __name__ =3D=3D '__main__': if len(sys.argv) not in [3, 4]: print """usage : %s [-o] <SOURCE> <DESTINATION> where <SOURCE> is the path of the source XML model and <DESTINATION> is where to save the PyModeling XML model Options : -o : only convert needed entities""" % (sys.argv[0]) sys.exit(1) onlyNeededEnts =3D "-o" in sys.argv =20 srcDoc =3D getSourceDom(sys.argv[-2]) newDoc =3D createDoc() importer =3D ModelingDDImporter(srcDoc, newDoc, onlyNeededEnts) importer.startConvertion() PrettyPrint(newDoc, stream=3Dopen(sys.argv[-1], "w")) # The END ! =2D --=20 Yannick Gingras Byte Gardener, Savoir-faire Linux inc. http://www.savoirfairelinux.com/ =2D----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2 (GNU/Linux) iD8DBQE/euJzrhy5Fqn/MRARAt/jAJ0eABfJZURbCLulDyX5oFRaR7DQvgCggzaz mNqOp1fTT8LkjVcH+KEnqIQ=3D =3Ds43u =2D----END PGP SIGNATURE----- |
From: Federico H. <fh...@vi...> - 2003-09-30 00:37:30
|
On Fri, 2003-09-26 at 19:05, Sebastien Bigaret wrote: > The framework needs to be in control of the mechanism generating the > primary keys --it needs to know the PK in advance so that > relationships (FK) and other changes can be changed in a single > roundtrip to the database. I know... this can be a bummer. In other instances when I had to solve this problem, I added to the driver a function that would return the PK assigned to the last insert (most DBMSs offer this one way or another, so a function in the driver can be used to unify the API). I would then assign a temp primary key to any new objects, and use it as a foreign key. Then, when the final PK is assigned, I'd go back and change the bogus foreign keys. It gets the job done, and it doesn't rely on additional tables on mysql and friends. On the other hand, it does require quite a bit of internal bookkeeping, so it may well not be worth the trouble. > I'm not really advocating it, it's just that I never played with it > because I considered a bit slower than horizontal: with 'nb' classes and > subclasses, [...] I never tried it --but my opinion has no real > weight here, remember I'm really not good at sql: that was one of the > motivation for writing the code :) Doh! And I was looking up at you for enlightenment! :-) Anyway, this may be a very good chance to compare horiz- vs vert-mapping, and see how they fare, don't you think? > You're perfectly right when you say > that the db will not be the bottleneck, the time taken by the framework > to build and manage the object graph will be greater anyhow. Indeed. But of course, when you have a few dozen hundred clients doing queries, things may look different. This is something we will have to find out sooner or later :-) > BTW if you have precise SQL examples on how you optimize the fetching > and updating of objects in a vertical mapping that could come in > handy! There's not much to optimize, actually. All you can do is cache the join sentence needed to fetch a given class, and create it carefully so you don't fetch unnecessary stuff nor check for redundant conditions, all of which is pretty straightforward... Fede |
From: SoaF-BSD <so...@la...> - 2003-09-29 22:20:34
|
On Saturday 27 September 2003 14:58, Yannick Gingras wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > On September 27, 2003 05:37, Mario Ruggier wrote: > > I see the XML just as an exchange format for a model, if you need > > to import, generate or export a model definition _programmatically_. > > IMHO, to develop your XML by hand is silly, as it is ugly, way too > > verbose, and very obscure and un-expressive -- it is very difficult > > (for me ;) to visualize a model from its XML definition. So, the XML > > should only be manipulated by tools -- in which case it does not > > matter whether properties are flattened or not. > > As I said some time ago, we use Datadesigner [1] to make our XML model and > than we pass it to a DOM transformation tool to have a Modeling > friendly document. Perhaps you can provide this tool ? add this to the CVS .. this could be great. no ? Bye Bye |
From: Yannick G. <ygi...@yg...> - 2003-09-29 21:59:58
|
=2D----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On September 27, 2003 05:37, Mario Ruggier wrote: > I see the XML just as an exchange format for a model, if you need > to import, generate or export a model definition _programmatically_. > IMHO, to develop your XML by hand is silly, as it is ugly, way too > verbose, and very obscure and un-expressive -- it is very difficult > (for me ;) to visualize a model from its XML definition. So, the XML > should only be manipulated by tools -- in which case it does not > matter whether properties are flattened or not. As I said some time ago, we use Datadesigner [1] to make our XML model and than we pass it to a DOM transformation tool to have a Modeling friendly document. XML is really easy to morph ! [1] : http://www.danny.cz/datadesigner.en.html =2D --=20 Yannick Gingras Coder for OBB : Observingly Blighted B.th.u. http://OpenBeatBox.org =2D----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2 (GNU/Linux) iD8DBQE/dYmKrhy5Fqn/MRARAl4LAJ9votpKlqT4RO60sXV3tuy9Gh+kdQCfWz8p eD/mKUkOth7p9SaXppCvAd8=3D =3DFYDg =2D----END PGP SIGNATURE----- |
From: Federico H. <fh...@vi...> - 2003-09-29 21:53:59
|
On Fri, 2003-09-26 at 07:05, Ernesto Revilla wrote: > I agree with Fede that this should be one of the priorities, cause it > has so many positive effects: > we can let modeling run in a 'heavy client', although this is not an > approach that I like, because I want the business logic on the server, > but.... > we can do load balancing with more servers, we can use different > editing contexts for each session, as already done with Zope, and > detect easily any update collisions. Each application should handle > collisions on it's own way. I agree that "heavy client" is not generally the way to go. However, if you solve that problem in a clean way, then you *know* everything else will work as well, and some interesting applications (like the load balancing you mention) become much easier. > I don't agree with Heinz on the fetch problem, because: As to this moment, I'm afraid I don't agree with Heinz either :-) Fede |
From: Sebastien B. <sbi...@us...> - 2003-09-28 22:23:18
|
Sebastien Bigaret <sbi...@us...> wrote: > "Ernesto Revilla" <er...@si...> wrote: > > I agree with Fede that this should be one of the priorities, cause it h= as so many positive effects: > > we can let modeling run in a 'heavy client', although this is not an ap= proach that I like, because I want the business logic on the server, but.... > > we can do load balancing with more servers, we can use different editin= g contexts for each session, as already done with Zope, and detect easily a= ny update collisions. Each application should handle collisions on it's own= way. >=20 > Absolutely, and I'll definitely post a plan for it this we.=20 I thought I'd have the time, but unfortunately I did not. That will be for the next few days, sorry for the delay. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-09-28 17:46:23
|
Hi all, I wrote: > As I wrote earlier, I'm working on dynamic creation of modules/classes > from a (py)model, either classic- or new-style (metaclass). That would > be an alternative to code generation that already exists. >=20 > Would anyone here have some time experimenting with an alpha release > of these features? If you think it would be of some interest in your First at all, thanks to all who replied they could possibly have some time to test it. I understand that your time is precious, and your help is really appreciated. I've just submitted patch #814055 at: https://sf.net/tracker/index.php?func=3Ddetail&aid=3D814055&group_id=3D5893= 5&atid=3D489337 You'll download from there the file Modeling-0.9pre15-dynamic.tar.gz. It consists of python files that should be dropped in the Modeling/ and Modeling/tests directory (see INSTALL in the tarball). Important note: you'll need the freshly released NotificationFramework v0.6 for this to work properly. For your information, I've included at the end of the message the complete README file included in the tarball, so that you can have an overview of the new features this introduces before choosing to test them. I've been asked how one can help; you may want to test that the three testsuites test_EC_Global, test_EC_Global_Inheritance and test_EC_ParentChild works with all three options '-c', 'm' and '-M' (described below) in your environment. Then of course, if you find some time to experiment it on your own models, I'll be happy to hear from that and the issues you might encounter, along with solving them, if needed. Thanks again for your time, -- S=E9bastien. ------------------------------------------------------------------------ --------------------------- Dynamic creation of classes --------------------------- :Authors: S=E9bastien Bigaret <sbi...@us...> Principles ---------- The module Modeling.dynamic has been added. It can be used in three different ways: * method build(model): dynamically build the package derived from the model. The generated package and its modules have the very same functionality as the ones generated by the script mdl_generate_python_code.py (in "base" mode, option ``-B``). * metaclass ``CustomObjectMeta``: automatically adds all the necessary methods to a class for integration with the modeling framework. It looks for the following attributes in the class: - ``entityName``: mandatory, this is the name of the class' entity. The corresponding model should have been loaded prior to the class declaration, or you'll get a dynamic.EntityNotFound exception. - ``verbose_metaclass``: if set, the metaclass prints on sys.stderr some info while building the class. - ``mdl_define_properties``: if set, the metaclass will also add properties for each attribute on relationship in the entity, so that you do not need anymore to use e.g. ``book.getTitle()`` or ``book.setTitle``, but simply ``print book.title`` or ``book.title=3D"my title"`` Note: this name is not definitive and will probably be changed before this is integrated into the core (same for metaclass, methods' names, etc.). Suggestions are welcome! * method ``build_with_metaclass(model, define_properties)``: builds the package and its module from a model. The generated modules and classes uses the ``CustomObjectMeta`` metaclass. Parameter ``define_properties`` triggers the creation of properties by the metaclass. This method raises ``NotImplementedError`` under python2.1, as expected. Note: The model will be loaded, as usually, from XML or PyModels, for example with Model.searchModel(). See e.g. tests/test_EditingContext_Global.py for an example. Example of use -------------- You find there three different examples on how these new features can be used:: ### Common to exs 1, 2 & 3: load the model from Modeling import ModelSet, Model, dynamic model=3DModel.searchModel('AuthorBooks', '.', verbose=3D1) ModelSet.defaultModelSet().addModel(model) =20=20 ### 1. example with dynamic.build() dynamic.build(model) from Modeling.EditingContext import EditingContext from AuthorBooks.Book import Book # fetch ec=3DEditingContext() print [b.getTitle() for b in ec.fetch('Book')] # create a new book b=3DBook(title=3D'mon titre') ec.insert(b) ec.saveChanges() =20=20 ### 2. example with dynamic.build_metaclass() dynamic.build_with_metaclass(model, define_properties=3D1) from Modeling.EditingContext import EditingContext ec=3DEditingContext() print [b.title for b in ec.fetch('Book')] from AuthorBooks.Book import Book b=3DBook(title=3D'mon titre7.2') ec.insert(b) ec.saveChanges() b.price=3D7.21 =20=20 ### 3. example with the metaclass class Book: __metaclass__=3Ddynamic.CustomObjectMeta entityName=3D'Book' mdl_define_properties=3D1 =20=20 class Writer: __metaclass__=3Ddynamic.CustomObjectMeta entityName=3D'Writer' mdl_define_properties=3D1 =20=20 # fetch and insert etc., as usual: from Modeling.EditingContext import EditingContext ec=3DEditingContext() b=3DBook(title=3D'book_w1') ; w1=3DWriter(lastName=3D'w1') ec.insert(b) ; ec.insert(w1) b.author=3Dw1 w1.addToBooks(b) ec.saveChanges() Tests ----- All three tests test_EC_Global.py, test_EC_Global_Inheritance.py and test_EC_ParentChild.py now accepts new options: * ``-c`` uses ``dynamic.build()`` * ``-m`` uses ``dynamic.build_with_metaclass(model, define_properties=3D0= )`` * ``-M`` uses ``dynamic.build_with_metaclass(model, define_properties=3D1= )`` * without any of these options, they use the test packages in tests/testPackages as in the standard distribution. Note: they all require that you copy the pymodels pymodel_AuthorBooks.py (in testPackages/AuthorBooks/) and pymodel_StoreEmployees.py (in (testPackages/StoreEmployees/) in the tests/ directory. Changes ------- Some classes have been changed to derive from ``object``, when available (python v2.2+), just because I've noted that this results in slightly better performance; however, this has nothing to do with the dynamic creation of classes. Among those classes that are now new-style classes: CustomObject. When it is integrated into the framework, this will probably be left as a choice for the user: since this transforms any user-class inheriting from CustomObject into new-style classes, this can have unexpected side-effects in other portions of the user's code (for example, ``type(object)=3D=3DInstanceType`` for classic-style classes, while it equals to ``obj.__class__`` for new-style classes). ------------------------------------------------------------------------ |
From: Sebastien B. <sbi...@us...> - 2003-09-28 00:32:57
|
Hi all, The notification center, one of the key component in the mdl framework, did not handle py2.2+ new-style classes observers correctly. This caused various failures when they were used within the modeling framework. Release 0.6 adds full support for observers being instances of new-style classes. After upgrading, it is possible to use them with the modeling framework. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-09-28 00:06:22
|
> While working at the dynamic creation of classes, I've just noticed > that new-style classes are not well handled by the framework... which > is a polite way of saying that they do not work at all. >=20 > The problem appears to be in the NotificationFramework, a key component > heavily used in the core. I'm currently investigating the issue. It's confirmed. Still have a few tests to do, but this seems solved now. Expect a release announcement soon. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-09-27 15:19:47
|
Mario Ruggier <ma...@ru...> wrote: [about usedForLocking] > > This flag indicates which attributes optimistic locking will check when > > it is about to save changes: if value for attribute 'lastname' has > > changed and 'usedForLocking' is set for tha attr., then under the > > optimistic locking policy saveChanges() will raise; if the flag is > > unset, the attribute will be silently overriden (for example, you > > probably won't mark an object's timestamp as used for locking). >=20 > OK, thanks. But this paragraph should also be copy'n'pasted into > in section "2.3.3 Attribute" of the userguide... Right. Added ticker #813586 for that, thanks for noticing. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-09-27 15:14:51
|
Hi Mario, Mario Ruggier <ma...@ru...> wrote: > Hi, sorry about the late jump-in, just a few comments: No problem :) > I see the XML just as an exchange format for a model, if you need > to import, generate or export a model definition _programmatically_. > IMHO, to develop your XML by hand is silly, as it is ugly, way too > verbose, and very obscure and un-expressive -- it is very difficult > (for me ;) to visualize a model from its XML definition. So, the XML > should only be manipulated by tools -- in which case it does not > matter whether properties are flattened or not. As far as flattened properties are concerned, implementing them will add new declaration(s) in either the xml-model or the pymodel, in a completely backward compatible way. And yes, now that we have pymodels, we can say that designing a xml-model by hand is unappropriate :) > However, if one still wants a more human-friendly XML, what's the > problem with either assigning generic default values for xml element > attribs (e.g. parentEntity=3D'', isReadOnly=3D'0', isAbstract=3D'0', etc= , if > not present), or "inferring" the value of specific attribs from the > parent entity if one is set. Elements are "identified" by they nodename > and by the value of the name attribute. For example, the famous > Employee entity can become (leaving out PK, and Rels for simplicity) : [snipped example] > The default values are more "limited" than in PyModels, as they apply > to nodeType[@name]/@attrib, and to nodeType[@name]/* (children). > It is then a matter of pre-processing to generate from the above the > same identical full XML for these 2 entities as in the current > StoreEmp example, thus no runtime code would need to be touched > in any way. The pre-processing could be done also as an XSL > transformation or so, or with any old dom manipulation technique. > Also, no backwards compatibility issues, as if something is specified > explicitly, then it is not affected by this mechanism. >=20 > But, I question whether doing all this is worth it... in the end it will > still always be way more cumbersome than PyModels (also in > performance!). I really do not feel like going that way; xml-models are a complete dump on models in memory at runtime, they are advertized as-is, and I have the strong feeling that this should remain untouched. First, because xml has no declared explicit way of specifying defaults, except those declared in the classes Model, Entity, etc., but that's not explicitely supported, nor recommended, nor checked, and changing the defaults in these classes could possibly slightly change the semantics of some fields in the xml --while on the other hand the pymodels have an explicit mechanism for notifying changes between version, that's the model's attribute 'version'. Second, because introducing such a feature (lighter xml for inheritance), apart from representing a real work, will probably not be used at all: as you noted, even with this, all in all they would remain far more cumbersome than pymodels. > Hey, and it can also generate the xml so trivially ;) One more reason, I'd say ;) May I repeat it again, all this does *not* mean that xml-models are about to be deprecated. People are using it in various ways, including auto-generating them from other xml-sources. It just means that we won't probably change the way it is now: an explicit, comprehensive serialization of models used at runtime. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-09-27 14:40:07
|
Hi all, While working at the dynamic creation of classes, I've just noticed that new-style classes are not well handled by the framework... which is a polite way of saying that they do not work at all. The problem appears to be in the NotificationFramework, a key component heavily used in the core. I'm currently investigating the issue. If the bug is confirmed, I'll immediately make a new release for the notification framework and will keep you informed here. I've also opened ticket #813562 for this purpose https://sf.net/tracker/index.php?func=3Ddetail&aid=3D813562&group_id=3D5893= 5&atid=3D489335 Regards, -- S=E9bastien. |
From: Mario R. <ma...@ru...> - 2003-09-27 09:57:15
|
Hi, how do people handle updating an existing database (with data) for changes in the model? The py code aspect is OK, but how is the db updated? Does one have to mess around in SQL on a change case-by-case basis, or is there a way to "automate" this more? Such as a modeling-based script to populate a completely new db (with new model) from the old db? Assuming the model plays nicely, letting the framework auto-handle all pk values and relationships, is such a tool possible? mario |
From: Mario R. <ma...@ru...> - 2003-09-27 09:44:49
|
Hi, sorry about the late jump-in, just a few comments: On Jeudi, sep 25, 2003, at 21:36 Europe/Zurich, Sebastien Bigaret wrote: > Federico Heinz <fh...@vi...> wrote: >> On Thu, 2003-09-25 at 10:37, Sebastien Bigaret wrote: [...] >> This makes writing the XML by hand a major >> pain in the neck, though it probably doesn't matter (at least to us, >> we're planning on generating this XML from our own, richer XML >> dstabase >> schema description). > > XML-models have no default value, in fact they are a comprehensive > description of the models, so in general designing them by hand is a > pain --that's why the ZModeler was written, and also why PyModels are a > great win :) Note that in PyModels, properties do not need to be copied > from parent to children, this is done automatically. I see the XML just as an exchange format for a model, if you need to import, generate or export a model definition _programmatically_. IMHO, to develop your XML by hand is silly, as it is ugly, way too verbose, and very obscure and un-expressive -- it is very difficult (for me ;) to visualize a model from its XML definition. So, the XML should only be manipulated by tools -- in which case it does not matter whether properties are flattened or not. However, if one still wants a more human-friendly XML, what's the problem with either assigning generic default values for xml element attribs (e.g. parentEntity='', isReadOnly='0', isAbstract='0', etc, if not present), or "inferring" the value of specific attribs from the parent entity if one is set. Elements are "identified" by they nodename and by the value of the name attribute. For example, the famous Employee entity can become (leaving out PK, and Rels for simplicity) : <entity name='Employee'> <attribute width='50' precision='0' externalType='VARCHAR' name='lastName' scale='0' type='string'/> <attribute width='20' isRequired='0' precision='0' externalType='VARCHAR' name='firstName' scale='0' type='string' /> <attribute ... name='fkStoreId' ... /> </entity> And, if we now declare SalesClerk, that inherits from Employee, we could get away with: <entity name='SalesClerk' parentEntity='Employee' > <attribute width='20' precision='0' externalType='VARCHAR' name='storeArea' scale='0' type='string' /> </entity> The default values are more "limited" than in PyModels, as they apply to nodeType[@name]/@attrib, and to nodeType[@name]/* (children). It is then a matter of pre-processing to generate from the above the same identical full XML for these 2 entities as in the current StoreEmp example, thus no runtime code would need to be touched in any way. The pre-processing could be done also as an XSL transformation or so, or with any old dom manipulation technique. Also, no backwards compatibility issues, as if something is specified explicitly, then it is not affected by this mechanism. But, I question whether doing all this is worth it... in the end it will still always be way more cumbersome than PyModels (also in performance!). > BTW: there is a reason why models requires properties to be copied: a > string attribute in a parent can have a width of 40, while a child > can > ask a width of 50 for the same field. Since model introspection is > something the framework does a lot, we do not want to compute > inherited attributes if they are not overriden: that's why they are > copied. And since xml-models are comprehensive descriptions of > models, > you also find copy of inherited attributes in entities. > > PyModels takes care of this when loaded, although they also allow > you to override the definitions of inherited attributes, if needed. > The best of the two worlds ;) Hey, and it can also generate the xml so trivially ;) mario |