modeling-users Mailing List for Object-Relational Bridge for python (Page 12)
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: Clay <ho...@ho...> - 2004-05-08 14:35:07
|
Hi folks, First off, let me say that I'm pretty impressed with what you have started here. I've been in a similar situation a few times, and decided something like this was sorely needed, but never had the time to put anything quite so coherent together to address it. So, nice work. I'm trying to get started small, and have hit a question. I'm trying to think of this in terms of having the 'pymodel' file be the central repository for schema related issues. That seems to be the design intent anyway -- and really how I would like to do things (central location). Suppose I'm going to implement /etc/passwd /etc/group type concepts. This gives 'user' 'group' and 'usergroup' entities, plus associations. Great. using groupID and userID as the primary keys, and the correlation table is the tuple of the two. Heres' my issue. Clearly you want to enforce uniqueness of username (strings) as well as user-ids and integer primary keys. Further, this is something you need the DBMS to enforce. Since I'm effectively specifying my schema in pymodel, it would seem reasonable to be able to add this type of constraint to that specification. Either that, or have a coherent way of maintaining them separatly in a non-disjoint sort of way. Looking for either something I've missing in the modelling, or a good technique to handle this class of problem. Thanks, Clay Hopperdietzel |
From: Sebastien B. <sbi...@us...> - 2004-04-29 20:13:47
|
Hi Stephen, Stephen Nesbitt <sne...@co...>: > All: > > A couple of quick (I hope) newbie questions. > > First what is the canonical way to override the the database access stuff > embedded in the model? Essentially I've modeled our production database, but > want to validate and test against a test database without modifying the model > I'd say the canonical way is to create a file, say, test_DB.cfg, that overwrite the necessary db-connection dict. (host, port, user, password) Then set the env. variable MDL_DB_CONNECTIONS_CFG to the full path of this .cfg file, and it will be automatically used to overwrite the specified field with the associated values just after the model is loaded. See http://modeling.sourceforge.net/UserGuide/env-vars-core.html for details. However, please do some testing before trying to drop the whole database!! --probably the best way to avoid shooting yourself in the foot is to remove the user/password/host/port stuff from your model, and have two deidacted db_config.cfg file, one on the production machine, the other one on the test machine. This way if you forget to set the env. variable you won't hit the production db, just get some errors. > Second, how do I handle commits and rollbacks? I had an instance were I had a > failed transaction and ended up with a hung transaction and no obvious way to > roll it back. > > Thanks in advance! Could you be more specific? Do you have an example? Normally the framework does/should do all the commit or rollback stuff for you, it shouldn't leave a opened transaction. What do you mean exactly by a "hung transaction"? (BTW: which db do you use?) If this is a bug, we'd better be able to reproduce it to get rid of it :-/ -- Sébastien. |
From: Stephen N. <sne...@co...> - 2004-04-28 21:39:20
|
All: A couple of quick (I hope) newbie questions. First what is the canonical way to override the the database access stuff embedded in the model? Essentially I've modeled our production database, but want to validate and test against a test database without modifying the model in advance. Second, how do I handle commits and rollbacks? I had an instance were I had a failed transaction and ended up with a hung transaction and no obvious way to roll it back. Thanks in advance! -steve -- Stephen Nesbitt Senior Configuration Management Engineer The Cobalt Group 206.219.8271 sne...@co... |
From: Sebastien B. <sbi...@us...> - 2004-04-27 19:14:36
|
Matthew Patton <pa...@dm...> wrote: > Hello Sebastien et al, > It's been a while since Tom and I posted on this list, and we just > wanted to let you know of our final decision to go with J2EE instead of > trying to develop an Enterprise Application Framework in Python. Since > J2EE provides everything we need and there are good open source > implementations available (JBoss, Jonas), we felt it would not be our > place to reinvent these low-level architectural tools. We're now > commencing development in J2EE on a receipting system as part of a larger > project for providing OSS software for non-profits (URL: > http://daniel.sf.net/). Thanks for all of your help and for the > interesting discussions and input. Oh well, too bad you've decided to leave the wonderful and colorful world of python ;) Anyhow, be sure that the discussions you and Tom triggered / participated in will eventually make the User's Guide better one day! Wishing you good luck for the future and your projects, cheers, -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2004-04-27 19:08:33
|
John Lenton <jo...@vi...> wrote: > agreed, and I think I pointed out (I know I tried to point out) the > second one of these. However the first is what I understood was being > requested. Seems like I misunderstood your post, sorry > The way I think I'd *like* to solve the second one is along the lines of >=20 > ec.fetch('Writer.books.publisher', unique=3DTrue) >=20 > or, perhaps (if something sensible can be found to fill in the > ellipsis), >=20 > ec.fetch('Writer.books.publisher', groupBy=3D'...') >=20 >=20 > The first could be ameliorated by having fetch return an iterator > instead of a list... [+ more on "smarter lists", such as algebra sets] Interesting idea indeed, I'm afraid i've not enough time to comment on this now though. Should I forget about it, you can recall me of your comments in= a week when I'll be back online. Even if it sounds like dropping support for py2.1 (not sure however), it seems bright enough to be worth the investigation ;) [do not misunderstannd me here, I do not plan to drop support for py2.1 by now] > References: > 1) http://www.cs.sfu.ca/CC/354/zaiane/material/notes/Chapter3/node7.html Still did not find the time or energy :) to look at the reference, but I promise we'll discuss this deeper. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2004-04-27 19:02:26
|
Mario Ruggier <ma...@ru...> wrote: > > Almost... because EXISTS applies to a independent subquery, while the o= ther > > keywords are constraints on the current query. Would this be a possible= source > > of confusion? > >=20 > > What happens if we intermix these keywords, e.g. > >=20 > > ec.fetch('Writer', 'books.publisher.numPages>50 > > AND (books.publisher.bizName IN ["P1","P2"]) > > AND NOT EXISTS(books.publisher.bizName NOT IN ["P1","p2"] ) ' > >=20 > > to get the authors that have books with at least 51 pages as well as ha= ving > > published with both of P1 and P2 but with no one else. Would this work?= There > > would be a simpler way to do this? > oops, sorry, just realized that's pretty silly. Lousy example... > Make that something like: >=20 > ec.fetch('Writer', 'books.publisher.numPages>50 > AND (books.publisher.bizName IN ["P1","P2"]) > AND NOT EXISTS(books.publisher.country NOT IN ["c1","c2"] ) ' >=20 > or so... Not a problem:) My idea of this is that everything should nicely play one w/ the other, or we'll lose most of the feature, so we should be able to intermix every keyword w/o problem. I'll play with this some day for sure. To be more precise, in our case (a fetchspec) EXISTS do apply to an independent query but this query is always bound to the original one: look at this: =3D# SELECT DISTINCT t0.ID, t0.LAST_NAME, t0.FIRST_NAME, t0.AGE, -# t0.FK_WRITER_ID, t0.BIRTHDAY -# FROM WRITER t0 -# WHERE NOT EXISTS (SELECT * FROM BOOK,WRITER,PUBLISHER (# WHERE WRITER.ID=3Dt0.ID (# AND WRITER.ID=3DBOOK.FK_WRITER_ID=20 (# AND BOOK.FK_PUBLISHER=3DPUBLISHER.ID (# AND PUBLISHER.BIZ_NAME!=3D'P1'); the second WHERE clause binds the "independent query" to the first one with WRITER.ID=3Dt0.ID. --> that's why I think this shouldn't be difficult to implement, but I need to experiment with nested EXISTS clause (I do not have enonugh sql knowledge to foresee the possible coming complications). BTW I'll will be mostly off for a week, not sure if I'll read email for that time, and I'll be back online for sure some day next week. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2004-04-27 18:52:21
|
Hi Aaron, "Aaron Freeman" <afr...@em...> writes: > First, thank you all for the fast and details replies; they are much > appreciated. ;-) >=20 > I've been playing around with the code that was posted, and while I still > don't have it working, it is getting closer. >=20 I'm sorry, I assumed py2.2+, not py2.1 We definitely still support py2.1, but of course then some of the features are not available. For example, there's nothing like properties in py2.1. The code I posted should work given that: - you replace p.bizname=3D"x" w/ p.setBizname("o") and p.bizname w/ the appropriate getter p.getBizname() (this will make the ValidationException at saveChanges() disappear) - you build the package/modules/classes w/: >>> build(model, define_properties=3D0) since py2.1 has no properties. And that's obviously what you discovered on your own. > 1) Based on some archived posts, I was under the impression that Modeling > core supports Python 2.1 (I am using 2.1.3 since this is leading up to a > Zope 2.6.4 product); is that still true? To be clear: yes, it is. > 2) Do I need the Modeling.dynamic module? This appears to require python > 2.2, but if the classes are being generated via an XML file or the ZModel= er > tool, this shouldn't be required, right? You absolutely do not need too, right. I just use it (even though it's not documented yet) since most people tends to think its the easiest way (including me :) --but that does not mean that code generation, either from the ZModeler or from mdl_generate_python_code.py, is deprecated. -- S=E9bastien. |
From: Matthew P. <pa...@dm...> - 2004-04-27 14:44:27
|
Hello Sebastien et al, It's been a while since Tom and I posted on this list, and we just wanted to let you know of our final decision to go with J2EE instead of trying to develop an Enterprise Application Framework in Python. Since J2EE provides everything we need and there are good open source implementations available (JBoss, Jonas), we felt it would not be our place to reinvent these low-level architectural tools. We're now commencing development in J2EE on a receipting system as part of a larger project for providing OSS software for non-profits (URL: http://daniel.sf.net/). Thanks for all of your help and for the interesting discussions and input. Matt ______________________________________________________________ Matthew Patton pa...@dm... DiscipleMakers Headquarters: (814)234-7975 x32 |
From: John L. <jo...@vi...> - 2004-04-21 22:12:23
|
Sender: John Lenton <jo...@ma...> On Tue, Apr 20, 2004 at 11:46:10PM +0200, Sebastien Bigaret wrote: > > Yes, that's another approach indeed. But while I'm a fervent defender > for KeyValueCoding ;)) in such cases one should be careful. Here are > some thoughts: > > - if the database have a lot of books, the KVC approach will load them > all in memory: KVC traverses relationships at the object level, and > in this case this means fetching Books published by every Publisher, > then these Books' Authors. This is probably the worst case one can > get. That's probably why you were asking for a callable vFKP on a > class, weren't you? > > - In the resulting lists, if an author has published N books for a > publisher, the corresponding list will receive N duplicates for that > author. agreed, and I think I pointed out (I know I tried to point out) the second one of these. However the first is what I understood was being requested. The way I think I'd *like* to solve the second one is along the lines of ec.fetch('Writer.books.publisher', unique=True) or, perhaps (if something sensible can be found to fill in the ellipsis), ec.fetch('Writer.books.publisher', groupBy='...') The first could be ameliorated by having fetch return an iterator instead of a list... in fact... if fetch returned something smarter than a list, it might be possible to do something like ec.fetch('Writer') - \ ec.fetch('Writer', 'books.publisher.bizName == "P1"') this means ec.fetch returns a set, as in relational algebra[1] sets, which you can operate on. These set objects wouldn't perform the select on the database until you accessed them as sequences, so the above wouldn't even touch the database until someone used the result for something other than operating on other sets. Maybe 'fetch' is a bad name for a method returning something that hasn't actually fetched :) If this falls in the 'intersting, but show me the code' category, I'm afraid it'll have to wait :( On Wed, Apr 21, 2004 at 10:55:26PM +0200, Mario Ruggier wrote: > ec.fetch('Writer', 'books.publisher.numPages>50 > AND (books.publisher.bizName IN ["P1","P2"]) > AND NOT EXISTS(books.publisher.country NOT IN ["c1","c2"] ) ' well, that's the same as ec.fetch('Writer', 'books.publisher.numPages > 50 \ AND books.publisher.bizName IN ["P1", "P2"]') - \ ec.fetch('Writer', 'books.publisher.country IN ["c1","c2"]') right? References: 1) http://www.cs.sfu.ca/CC/354/zaiane/material/notes/Chapter3/node7.html -- John Lenton (jo...@vi...) -- Random fortune: Above all else -- sky. |
From: Mario R. <ma...@ru...> - 2004-04-21 20:55:34
|
> ec.fetch('Writer', 'books.publisher.numPages>50 > AND (books.publisher.bizName IN ["P1","P2"]) > AND NOT EXISTS(books.publisher.bizName NOT IN ["P1","p2"] ) ' oops, sorry, just realized that's pretty silly. Lousy example... Make that something like: ec.fetch('Writer', 'books.publisher.numPages>50 AND (books.publisher.bizName IN ["P1","P2"]) AND NOT EXISTS(books.publisher.country NOT IN ["c1","c2"] ) ' or so... mario |
From: Aaron F. <afr...@em...> - 2004-04-21 17:49:11
|
First, thank you all for the fast and details replies; they are much appreciated. ;-) I've been playing around with the code that was posted, and while I still don't have it working, it is getting closer. First, I tried the Sebastien's code example (called extended.py here); this is what I got: jabartik extendedTest # python2.1 extended.py Traceback (most recent call last): File "extended.py", line 70, in ? build(model, define_properties=1) File "/usr/lib/python2.1/site-packages/Modeling/dynamic.py", line 168, in build add_properties(c, e) File "/usr/lib/python2.1/site-packages/Modeling/dynamic.py", line 148, in add_properties prop=property(getattr(aClass, 'get'+part_func_name), NameError: global name 'property' is not defined I also tried loading (and tweaking for the added Publisher table) the AuthorBooks example into the Zope ZModeler tool and then using it generate the code skeletons and database schema; that worked just fine. I then tried using these along with the code from Sebastien's example with the via the python interpreter, which had some issues, as follows: >>> from Modeling.EditingContext import EditingContext >>> ec=EditingContext() >>> from AuthorBooks.Publisher import Publisher >>> from AuthorBooks.Writer import Writer >>> from AuthorBooks.Book import Book >>> p1=Publisher() >>> p1.bizname="P1" >>> ec.insert(p1) >>> ec.saveChanges() Traceback (most recent call last): File "<stdin>", line 1, in ? File "/usr/lib/python2.1/site-packages/Modeling/EditingContext.py", line 737, in saveChanges self.validateChanges() File "/usr/lib/python2.1/site-packages/Modeling/EditingContext.py", line 765, in validateChanges self.objectForGlobalID(gID).validateForSave() File "/usr/lib/python2.1/site-packages/Modeling/CustomObject.py", line 595, in validateForSave error.finalize() File "/usr/lib/python2.1/site-packages/Modeling/Validation.py", line 145, in finalize if self._dict: raise self Modeling.Validation.ValidationException: Validation for key OBJECT_WIDE_VALIDATION failed: - Validation of object <AuthorBooks.Publisher.Publisher instance at 0x849e07c> as a whole failed Validation for key bizname failed: - Key is required but value is void After some scratching, I realized that the setBizname method in Publisher.py, below, isn't getting called. def setBizname(self, bizname): "Change the Publisher / bizname attribute value" self.willChange() self._bizname = bizname Doing a dir(p1) revealed: >>> dir(p1) ['_CustomObject__editingContext', '_bizname', '_books', '_location', '_v_classDescription', 'bizname'] So the 'bizname' attribute is getting appended and self._bizname = bizname isn't getting called, which causes the insert to die since bizname is set to non-null in the database. Manually forcing it with a p1._bizname="xyz" and then doing an insert works fine. So, the questions: 1) Based on some archived posts, I was under the impression that Modeling core supports Python 2.1 (I am using 2.1.3 since this is leading up to a Zope 2.6.4 product); is that still true? 2) Do I need the Modeling.dynamic module? This appears to require python 2.2, but if the classes are being generated via an XML file or the ZModeler tool, this shouldn't be required, right? At any rate, thanks again for your time and help. -Aaron |
From: Mario R. <ma...@ru...> - 2004-04-21 08:20:43
|
Hello! I had come across these kind of limitations a few months ago... not developing at the moment, but I find the issue interesting... so, just my 2 centimes ;) > This makes me think that it could be nice to have something like > >>>> ec.fetch('Writer', 'NOT EXISTS(books.publisher.bizName!="P1")' I would say yes this would be very nice to have... and this almost seems to me a consistent and natural extension of what is supported already, i.e. 'AND', 'OR', 'NOT', 'IN', 'NOT IN', 'like', ilike', ... anything else? Almost... because EXISTS applies to a independent subquery, while the other keywords are constraints on the current query. Would this be a possible source of confusion? What happens if we intermix these keywords, e.g. ec.fetch('Writer', 'books.publisher.numPages>50 AND (books.publisher.bizName IN ["P1","P2"]) AND NOT EXISTS(books.publisher.bizName NOT IN ["P1","p2"] ) ' to get the authors that have books with at least 51 pages as well as having published with both of P1 and P2 but with no one else. Would this work? There would be a simpler way to do this? mario |
From: Sebastien B. <sbi...@us...> - 2004-04-20 21:46:07
|
John Lenton <jo...@vi...> writes: > On Tue, Apr 20, 2004 at 09:46:39AM -0700, Aaron Freeman wrote: [...] > > How would I get writers by publisher? > > > > More specifically, is there an elegant way to do a nested join in a sin= gle > > query, or do I just have to do a single writer-book join and then itera= te > > over the resultset for the second join? >=20 > I don't think so. I'd do it with >=20 > [ i.valueForKeyPath('books.author') for i in ec.fetch('Publisher') ] >=20 > which is clean enough for me. I guess what you'd want is for > valueForKeyPath to be callable on a class... :) Yes, that's another approach indeed. But while I'm a fervent defender for KeyValueCoding ;)) in such cases one should be careful. Here are some thoughts: - if the database have a lot of books, the KVC approach will load them all in memory: KVC traverses relationships at the object level, and in this case this means fetching Books published by every Publisher, then these Books' Authors. This is probably the worst case one can get. That's probably why you were asking for a callable vFKP on a class, weren't you? - In the resulting lists, if an author has published N books for a publisher, the corresponding list will receive N duplicates for that author. The one posted earlier: >>> ec.fetch('Writer', 'books.publisher.bizName=3D=3D"P1"') does not have these possible drawbacks. However and admittedly the dotted notation as it is designed for now can only handle one kind of semantics for to-many relationships: for example, there is no way to ask for authors whose books were published by one single publisher only. In other words, then you'll have to use KVC or plain python, traverse the relationships and check properties, or, hmmm, get back to plain SQL w/ things like: SELECT DISTINCT t0.ID, t0.LAST_NAME, t0.FIRST_NAME, t0.AGE, t0.FK_WRITER_ID, t0.BIRTHDAY FROM WRITER t0 WHERE NOT EXISTS (SELECT * FROM BOOK,WRITER,PUBLISHER WHERE WRITER.ID=3Dt0.ID AND WRITER.ID=3DBOOK.FK_WRITER_ID=20 AND BOOK.FK_PUBLISHER=3DPUBLISHER.ID AND PUBLISHER.BIZ_NAME!=3D'P1') just to get the authors who have no other publisher than P1. This makes me think that it could be nice to have something like >>> ec.fetch('Writer', 'NOT EXISTS(books.publisher.bizName!=3D"P1")' so that we could avoid having to write plain SQL just like above (yerk:) What do you all think? -- S=E9bastien. |
From: John L. <jo...@vi...> - 2004-04-20 18:57:27
|
Sender: John Lenton <jo...@ma...> On Tue, Apr 20, 2004 at 09:46:39AM -0700, Aaron Freeman wrote: > (1) Is there a debug flag somewhere that dump all SQL queries to the > console? >=20 > (2) How are nested joins accomplished? >=20 > For example, in the AuthorBooks schema, lets assume there is another table > called publisher that has a 1-M relationship with books, like so (sorry > about the formatting): >=20 > .........................................................................= ... > ............. > .+-----------+.(0,1)..............(0,*).+-------+.(0,*)..............(0,1= ).+ > .|..Writer...|<-author----------books->>|.Book..|<<-books-------publisher= ->| > .Publisher.|. > .|-----------|.(nullify)......(cascade).|-------|........................= ..| > .|.lastName..|..........................|.title.|........................= ..| > .bizName...|. > .|.firstName.|..........................|.price.|........................= ..| > .location..|. > .|.age.......|.(0,1)....................+-------+........................= ..+ > .|.birthday..|<-pygmalion--+.............................................= ... > ............. > .+-----------+.(nullify)...|.............................................= ... > ............. > =20 > .....|....................|..............................................= ... > ............ > ......+--------------------+.............................................= ... > ............. > .........................................................................= ... > ............. >=20 > How would I get writers by publisher? > > More specifically, is there an elegant way to do a nested join in a single > query, or do I just have to do a single writer-book join and then iterate > over the resultset for the second join? I don't think so. I'd do it with [ i.valueForKeyPath('books.author') for i in ec.fetch('Publisher') ] which is clean enough for me. I guess what you'd want is for valueForKeyPath to be callable on a class... :) --=20 John Lenton (jo...@vi...) -- Random fortune: Sobre toda cosa guardada guarda tu coraz=F3n, porque de =E9l emana la vida. -- Salom=F3n.=20 |
From: Sebastien B. <sbi...@us...> - 2004-04-20 18:54:49
|
Hi Aaron, "Aaron Freeman" <afr...@em...> wrote: > (1) Is there a debug flag somewhere that dump all SQL queries to the > console? Absolutely: set the environment variable MDL_ENABLE_DATABASE_LOGGING to any true value. For details, see: http://modeling.sourceforge.net/UserGuide/env-vars-core.html > (2) How are nested joins accomplished? > For example, in the AuthorBooks schema, lets assume there is another table > called publisher that has a 1-M relationship with books, like so (sorry > about the formatting): >=20 [... Writer <-author----books->> Book <<-books----publisher-> Publisher ...] > How would I get writers by publisher? >=20 > More specifically, is there an elegant way to do a nested join in a single > query, or do I just have to do a single writer-book join and then iterate > over the resultset for the second join? >=20 Yes, there is a dedicated way of doing this: use the dotted notation: >>> ec.fetch('Writer', 'books.publisher.bizName=3D=3D"P1"') returns every writer who published (at least) a book w/ publisher P1. The generated SQL query is (postgresql here): SELECT DISTINCT t0.ID, t0.LAST_NAME, t0.FIRST_NAME, t0.AGE, t0.FK_WRITER_ID, t0.BIRTHDAY=20 FROM WRITER t0=20 INNER JOIN ( BOOK t1 INNER JOIN PUBLISHER t2=20 ON t1.FK_PUBLISHER=3Dt2.ID ) ON t0.ID=3Dt1.FK_WRITER_ID WHERE t2.BIZ_NAME =3D 'P1'; > Code examples would be great! I'm including in the end of the message a PyModel named EAuthorBooks (E stands for Extended :) derived from the one used in the User's Guide, with sample data, demonstrating the approach. Regards, =20=20=20=20=20=20=20=20 -- S=E9bastien. PS: you'll need to setup a database before running the example, e.g. w/ postgresql: $ mdl_generate_DB_schema.py \ --admin-dsn "localhost:template1:postgres:" \ -v -C pymodel_extAutborBooks.py ------------------------------------------------------------------------ #! /usr/bin/env python # -*- coding: iso-8859-1 -*- "Extended AuthorBooks model, with a Publisher" from Modeling.PyModel import * ## # Defaults AFloat.defaults['precision'] =3D 10 AFloat.defaults['scale'] =3D 2 AString.defaults['width'] =3D 40 Association.defaults['delete']=3D['nullify', 'nullify'] Entity.defaults['properties'] =3D [ APrimaryKey('id', isClassProperty=3D0, isRequired=3D1, doc=3D'PK') ] ## # Adapt to fit your own configuration!! _connDict =3D {'database': 'EAUTHOR_BOOKS', 'host':'localhost', 'user':'postgres','password':''} model =3D Model('EAuthorBooks',adaptorName=3D'Postgresql', connDict=3D_connDict) model.doc =3D ' ... ' model.version=3D'0.1' model.entities =3D [ # Entity('Book', properties=3D[ AString('title', isRequired=3D1, columnName=3D'titl= e'), AFloat('price'), ], ), Entity('Writer', properties=3D[ AString('lastName',isRequired=3D1, width=3D30 ), AString('firstName'), AInteger('age', displayLabel=3D'Age'), ADateTime('birthday', usedForLocking=3D0), ] ), Entity('Publisher', properties=3D[ AString('bizName',isRequired=3D1), AString('location'), ] ), ] #--- model.associations=3D[ Association('Book', 'Writer', relations=3D['author', 'books'], delete=3D['nullify', 'cascade'], keys=3D['FK_Writer_Id', 'id']), Association('Writer', 'Writer', relations=3D['pygmalion', None], delete=3D['nullify', None], keys=3D['FK_Writer_id', 'id']), Association('Book', 'Publisher', relations=3D['publisher', 'books']) ] model.build() model=3Dmodel.component if __name__=3D=3D"__main__": #import pdb ; pdb.set_trace() =20=20 from Modeling.dynamic import build build(model, define_properties=3D1) from Modeling.ModelSet import defaultModelSet defaultModelSet().addModel(model) from Modeling.EditingContext import EditingContext ec=3DEditingContext() from EAuthorBooks.Publisher import Publisher from EAuthorBooks.Writer import Writer from EAuthorBooks.Book import Book # Initialization p1=3DPublisher(); p1.bizName=3D"P1" p2=3DPublisher(); p2.bizName=3D"P2" w1=3DWriter(); w1.lastName=3D"in p1" w2=3DWriter(); w2.lastName=3D"in p2" w3=3DWriter(); w3.lastName=3D"in p1 and p2" =20=20 b1w1=3DBook(); b1w1.title=3D"b1w1" b2w1=3DBook(); b2w1.title=3D"b2w1" b1w2=3DBook(); b1w2.title=3D"b1w2" b2w2=3DBook(); b2w2.title=3D"b2w2" b1w3=3DBook(); b1w3.title=3D"b1w3" b2w3=3DBook(); b2w3.title=3D"b2w3" ec.insert(p1); ec.insert(p2); ec.insert(w1); ec.insert(w2); ec.insert(w3) ec.insert(b1w1); ec.insert(b2w1); ec.insert(b1w2); ec.insert(b2w2) ec.insert(b1w3); ec.insert(b2w3) w1.addToBooks(b1w1); b1w1.author=3Dw1; w1.addToBooks(b2w1); b2w1.author= =3Dw1 w2.addToBooks(b1w2); b1w2.author=3Dw2; w2.addToBooks(b2w2); b2w2.author= =3Dw2 w3.addToBooks(b1w3); b1w3.author=3Dw3; w3.addToBooks(b2w3); b2w3.author= =3Dw3 b1w1.publisher=3Dp1; p1.addToBooks(b1w1) b2w1.publisher=3Dp1; p1.addToBooks(b2w1); b1w2.publisher=3Dp2; p2.addToBooks(b1w2) b2w2.publisher=3Dp2; p2.addToBooks(b2w2); b1w3.publisher=3Dp1; p1.addToBooks(b1w3) b2w3.publisher=3Dp2; p2.addToBooks(b2w3); ec.saveChanges() # query ec=3DEditingContext() print [w.lastName for w in ec.fetch('Writer', 'books.publisher.bizName=3D=3D"P1"')] # returns: w1 and w3 ec=3DEditingContext() print [w.lastName for w in ec.fetch('Writer', 'books.publisher.bizName=3D=3D"P2"')] # returns: w2 and w3 ------------------------------------------------------------------------ |
From: Aaron F. <afr...@em...> - 2004-04-20 16:46:58
|
(1) Is there a debug flag somewhere that dump all SQL queries to the console? (2) How are nested joins accomplished? For example, in the AuthorBooks schema, lets assume there is another table called publisher that has a 1-M relationship with books, like so (sorry about the formatting): ............................................................................ ............. .+-----------+.(0,1)..............(0,*).+-------+.(0,*)..............(0,1).+ -----------+. .|..Writer...|<-author----------books->>|.Book..|<<-books-------publisher->| .Publisher.|. .|-----------|.(nullify)......(cascade).|-------|..........................| -----------|. .|.lastName..|..........................|.title.|..........................| .bizName...|. .|.firstName.|..........................|.price.|..........................| .location..|. .|.age.......|.(0,1)....................+-------+..........................+ -----------+. .|.birthday..|<-pygmalion--+................................................ ............. .+-----------+.(nullify)...|................................................ ............. .....|....................|................................................. ............ ......+--------------------+................................................ ............. ............................................................................ ............. How would I get writers by publisher? More specifically, is there an elegant way to do a nested join in a single query, or do I just have to do a single writer-book join and then iterate over the resultset for the second join? Code examples would be great! Thanks for your time. -Aaron |
From: Sebastien B. <sbi...@us...> - 2004-04-19 19:27:56
|
Hi John and all, You'll find a patch solving the problem along w/ the corresponding unittests at sf.net, bug #938096: https://sourceforge.net/tracker/index.php?func=3Ddetail&aid=3D938096&group_= id=3D58935&atid=3D489335 Thanks for reporting! -- S=E9bastien. PS for Yannick: I still did not find the time to investigate any further about GNU Arch, but I will, this looks interesting (not to say about the new name for the framework...!-). Any comparison w/ subversion, BTW? > John Lenton <jo...@vi...> writes: > > $ python > > Python 2.3.3 (#2, Feb 24 2004, 09:29:20) > > [GCC 3.3.3 (Debian)] on linux2 > > Type "help", "copyright", "credits" or "license" for more informati= on. > > >>> from Modeling.EditingContext import EditingContext > > >>> ec=3DEditingContext() > > >>> ec.fetch('foo', 'orbit > 3') > > Traceback (most recent call last): > > File "<stdin>", line 1, in ? > [...] > > raise ValueError, "Syntax error near token: `%s'" % token > > ValueError: Syntax error near token: `<Token OR>' > >=20 > > actually there's the same problem with any token: OR, AND, IN, or > > NOT. Is this a known problem in spark? is my spark version wrong? > > spark is 0.6.1, Modeling is 0.9-pre-16-patch892454. >=20 >=20 > This is a bug, unfortunately not fixed on sf yet :/ I'll have a look at = it > tonite. In the meantime you can build the same qualifier by hand: >=20 > >>> from Modeling.Qualifier import * > >>> q=3DKeyValueQualifier('foo', QualifierOperatorGreaterThan, 3) > >>> print q > (foo>3) > >>> ec.fetch('foo', q) >=20 > You can have a look at test_Qualifier.py for other examples. |
From: Yannick G. <ygi...@yg...> - 2004-04-16 16:43:22
|
=2D----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On April 16, 2004 08:25 am, Sebastien Bigaret wrote: > =A0 =A0 def _setMyAttribute(self, value): > =A0 =A0 =A0 =A0 self.value=3Dbool(value) > > (this is in fact the very same technique exposed here: > =A0http://modeling.sourceforge.net/UserGuide/attribute-custom-type.html) > > > =A0 =A0 If it's not what you need, could you also give a little example? Thats exactly what I need (except that I want an int instead of a bool) ! Thanks ! : ) > =A0 and I'll have a look at Arch when I find time ;) =A0Any idea on wheth= er > =A0 it wirks on sf? What is nice about Arch is that is does not need any support on the server side. Any remote file storage method will work, FTP, SFTP, WebDav, NFS... There is a ViewArch script to give the same functionality as ViewCVS. You can also have free hosting on sourcecontrol.net as long as your archive contain only free software. Sourcecontrol.net offers some more Arch centric support like remote branch searching and they are in the process to add website and release hosting too. The Emacs vc-arch mode also made it's way in the Emacs CVS so we can expect to see it in the next release. Compared to Subversion, the other likely replacement for CVS, Arch standout because it does not require special action on the server, it already support symlinks and you have GPG signature of commits which is quite an important feature with all the recent development server compromises. Both support renaming and moving but Arch can detect it without notifications without breaking history if you use tag-lines. Thats quite a nice feature if you come up with the new name one of these days... ; ) Get more information here: http://wiki.gnuarch.org/ =2D --=20 Yannick Gingras "Let's say the docs present a simplified view of realit= y" Coder for OBB : Obliquely Berserk Bookstore -- Larry Wa= ll http://OpenBeatBox.org =2D----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFAgA0jZJ8/OobqizMRAoacAJ9TmW9EFYfoIpwW6S9Xth+3jmm8WACgg7ZP 9W8GP89mmfusGsJhpL2jXUA=3D =3DchOf =2D----END PGP SIGNATURE----- |
From: Sebastien B. <sbi...@us...> - 2004-04-16 12:25:43
|
Hi Yannick, Not sure I fully understand what effect you want here, just in case this can help: you can transform any attribute's value stored as an int in the db into py2.3 boolean automaticall=3Dy by using a KeyValueCoding private setter, like that: def _setMyAttribute(self, value): self.value=3Dbool(value) (this is in fact the very same technique exposed here: http://modeling.sourceforge.net/UserGuide/attribute-custom-type.html) If it's not what you need, could you also give a little example? (admittedly I've read your msg quickly and answering the same way...) and I'll have a look at Arch when I find time ;) Any idea on whether it wirks on sf? -- S=E9bastien. Yannick Gingras <ygi...@yg...> writes: > Hi,=20 > we just upgraded to Python 2.3. As you probably know, Python 2.3 > now has a boolean type so repr(a =3D=3D b) is no longer 0 or 1 but True or > False. >=20 > We use some int(1) in our database to represent booleans but now all > our queries involving those fields are broken. >=20 > This is absolutely not a Modeling problem but I think that I can use > Modeling to reconvert those values just before the query. That would > solve quite a lot of work here. >=20 > Any of you guys had the same problem when switching to Python 2.3 ? >=20 > Should I tweak Modeling to make the conversion automatically ? Can it > break anything somewhere else ? >=20 > And absolutely unrelated to this problem, I've been using GNU Arch > lately instead of CVS. It features GPG signed commits and ease > maintaining branches in synch. If Modeling used Arch, we could make > the changes to automate booleans conversions in our branch and still > stay up to date with the main branch in case someone else would like > to have this particular feature and Sebastian find our code too ugly > to be merged yet... >=20 > ; ) >=20 > Enough propaganda, thanks for your time guys ! >=20 |
From: Sebastien B. <sbi...@us...> - 2004-04-16 12:23:05
|
Hi John, John Lenton <jo...@vi...> writes: > Hi there, long time no see :) >=20 > First, sorry for my delay with the cimarron example. I've had to stop > working on cimarron for a while... Not a problem, 'having a hard time here as well :) > Now I'm working with Modeling in zope, and I seem to have come across > a bug... and I'm hoping there's an easy fix (or that it's already > fixed and I've just not seen it on sourceforge :p). >=20 > $ python > Python 2.3.3 (#2, Feb 24 2004, 09:29:20) > [GCC 3.3.3 (Debian)] on linux2 > Type "help", "copyright", "credits" or "license" for more information. > >>> from Modeling.EditingContext import EditingContext > >>> ec=3DEditingContext() > >>> ec.fetch('foo', 'orbit > 3') > Traceback (most recent call last): > File "<stdin>", line 1, in ? [...] > raise ValueError, "Syntax error near token: `%s'" % token > ValueError: Syntax error near token: `<Token OR>' >=20 > actually there's the same problem with any token: OR, AND, IN, or > NOT. Is this a known problem in spark? is my spark version wrong? > spark is 0.6.1, Modeling is 0.9-pre-16-patch892454. This is a bug, unfortunately not fixed on sf yet :/ I'll have a look at it tonite. In the meantime you can build the same qualifier by hand: >>> from Modeling.Qualifier import * >>> q=3DKeyValueQualifier('foo', QualifierOperatorGreaterThan, 3) >>> print q (foo>3) >>> ec.fetch('foo', q) You can have a look at test_Qualifier.py for other examples. HTH, -- S=E9bastien. |
From: Yannick G. <ygi...@yg...> - 2004-04-15 23:58:50
|
=2D----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi,=20 we just upgraded to Python 2.3. As you probably know, Python 2.3 now has a boolean type so repr(a =3D=3D b) is no longer 0 or 1 but True or =46alse. We use some int(1) in our database to represent booleans but now all our queries involving those fields are broken. This is absolutely not a Modeling problem but I think that I can use Modeling to reconvert those values just before the query. That would solve quite a lot of work here. Any of you guys had the same problem when switching to Python 2.3 ? Should I tweak Modeling to make the conversion automatically ? Can it break anything somewhere else ? And absolutely unrelated to this problem, I've been using GNU Arch lately instead of CVS. It features GPG signed commits and ease maintaining branches in synch. If Modeling used Arch, we could make the changes to automate booleans conversions in our branch and still stay up to date with the main branch in case someone else would like to have this particular feature and Sebastian find our code too ugly to be merged yet... ; ) Enough propaganda, thanks for your time guys ! =2D --=20 Yannick Gingras "please call it ``GNU/Linux'= '" Coder for OBB : Officious Billowing Bailey -- Richard M. Stallm= an http://OpenBeatBox.org =2D----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFAfyG1ZJ8/OobqizMRAvk8AKDojHEvO8hdhLmk1xMtKfZMn4aKxwCeIhq9 quoHiRK/W5PBstlw9qs+DOE=3D =3Dk51v =2D----END PGP SIGNATURE----- |
From: John L. <jo...@vi...> - 2004-04-15 21:19:35
|
Sender: John Lenton <jo...@ma...> Hi there, long time no see :) First, sorry for my delay with the cimarron example. I've had to stop working on cimarron for a while... Now I'm working with Modeling in zope, and I seem to have come across a bug... and I'm hoping there's an easy fix (or that it's already fixed and I've just not seen it on sourceforge :p). $ python Python 2.3.3 (#2, Feb 24 2004, 09:29:20)=20 [GCC 3.3.3 (Debian)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from Modeling.EditingContext import EditingContext >>> ec=3DEditingContext() >>> ec.fetch('foo', 'orbit > 3') Traceback (most recent call last): File "<stdin>", line 1, in ? File "/usr/lib/python2.3/site-packages/Modeling/EditingContext.py", l= ine 1413, in fetch qualifier=3DqualifierWithQualifierFormat(qualifier) File "/usr/lib/python2.3/site-packages/Modeling/Qualifier.py", line 1= 29, in qualifierWithQualifierFormat return QualifierParser.qualifierWithQualifierFormat(expression) File "/usr/lib/python2.3/site-packages/Modeling/QualifierParser.py", = line 550, in qualifierWithQualifierFormat _parse=3Dparse(sc) File "/usr/lib/python2.3/site-packages/Modeling/QualifierParser.py", = line 417, in parse return parser.parse(tokens) File "/usr/lib/python2.3/site-packages/spark.py", line 204, in parse self.error(tokens[i-1]) File "/usr/lib/python2.3/site-packages/Modeling/QualifierParser.py", = line 261, in error raise ValueError, "Syntax error near token: `%s'" % token ValueError: Syntax error near token: `<Token OR>' actually there's the same problem with any token: OR, AND, IN, or NOT. Is this a known problem in spark? is my spark version wrong? spark is 0.6.1, Modeling is 0.9-pre-16-patch892454. --=20 John Lenton (jo...@vi...) -- Random fortune: Teme a la vejez, pues nunca viene sola. -- Plat=F3n. (427-347 a.C.) Fil=F3sofo griego.=20 |
From: Sebastien B. <sbi...@us...> - 2004-04-14 19:22:41
|
Hi, ...And sorry for the late answer Luciano Andrade <and...@ya...> wrote: > I whant to know what meens the attributeUseForLooking, The 'usedForLocking' property is not used yet --it will be used to indicate which attributes should be monitored when the forthcoming optimistic locking feature is implemented. > what mees that a relation is a classpropety, what if > a propiety is not a classpropety,=20 The 'classProperty' flag indicates whether the related attribute is part of the class' attributes. For example, 'firstName' is a class property in entity Person: any object of class Person has a property 'firstName'; on the contrary, the primary key is not a class property, it is just a column in the database that is not exposed at the object level (so in this case the DB's table has a 'id' column but class Person does not have any 'id' attribute) > what the join's semantics meens, This has to do with different sets of objects returned by a SQL query --I myself only use inner joins (ie themost natural one, at least for me;), so instead of trying to explain things I do not master at all, I prefer to give you some links that ill do the job better then I could: Getting the Right Data with SQL Joins: http://www.devx.com/dbzone/Article/17403/0/page/1 =20=20 Fropm postgresql: http://www.postgresql.org/docs/7.4/interactive/tutorial-join.html =20=20 O'Reilly: (pointed to by: http://www.onlamp.com/pub/ct/19) =20=20 http://www.onlamp.com/pub/a/onlamp/2001/05/24/aboutSQL.html http://www.onlamp.com/pub/a/onlamp/2001/06/01/aboutSQL.html http://www.onlamp.com/pub/a/onlamp/2001/06/15/aboutSQL.html http://www.onlamp.com/pub/a/onlamp/2001/06/27/aboutSQL.html > what about circular relations, can the module handled. Not sure what you mean: do you mean reflexive relationships, i.e. where the source and destination entities are the same entity? If this is the case, have a look at the sample model in the User's Guide: http://modeling.sourceforge.net/UserGuide/model-author-books.html It has a reflexive relationship Writer-->Writer (it is a directional relationship, but you can have a one-to-many bi-directional relationship as easily), which is modeled exactly the same than "standard" relationships. The corresponding PyModel is exposed here: http://modeling.sourceforge.net/UserGuide/pymodel-sample.html Should you have other questions, feel free to ask for more here! -- S=E9bastien. |
From: <and...@ya...> - 2004-04-11 22:14:31
|
I whant to know what meens the attributeUseForLooking, what mees that a relation is a classpropety, what if a propiety is not a classpropety, what the join's semantics meens, what about circular relations, can the module handled. ------------ Los mejores usados y las más tentadoras ofertas de 0km están en Yahoo! Autos. Comprá o vendé tu auto en http://autos.yahoo.com.ar |
From: Sebastien B. <sbi...@us...> - 2004-03-25 22:33:11
|
Marcos Dione <md...@vi...> wrote: > On Thu, Mar 25, 2004 at 01:03:00AM +0100, Sebastien Bigaret wrote: > > Repopulating the EC simply consists in fetching the objects, or asking > > for a particular object given its globalID (ec.faultForGlobalID()), etc. >=20 > well, I was thinking in that yesterday when I left work... is it too > ugly to do it that way? will it mess with something? No it's not: GlobalIDs are especially designed to designate a specific object/row, and using a child EC has several advantages. I was just saying then that the features it provides [mostly: "OO-transactions" and inheriting the changes made in the parent EC(s)] may be oversized if all you need is to forget the state of one or a few objects. And if you mess with something when doing it this way, that means you've probably been bitten by a bug. > [...] > --- paste --- > I've quickly checked the implementation & at the test I proposed there, > so here is my suggestion: you can use it as-is, given that: >=20=20=20=20=20 > - you're not applying it on deleted, inserted or modified objects, (BTW: > it will become an error to refault a deleted or an inserted object) > [UPDATE: see note, below] >=20 > - you stick to EC.refaultObject and do not try to call > DBContext.refaultObject >=20=09=20=20=20 > - you do not use it with a nested ec. >=20=09=20=20=20=20 > (I'm not saying this won't work, it probably will... but it needs to be > tested before I can say this is supported). > --- paste --- >=20 > that last remark applies to the last contition? from the patch, it > seems like the refaultObject is finally done by the 'master' of all the > EC's. do you think the problem would be that the 'reset' is not > 'propagated' to children EC's? - Exactly, it is indeed propagated down the EC hierarchy, then to the ObjectStoreCoordinator and ultimately to the DatabaseContext responsible for the object's entity. - The last remark was targetted to the three conditions. You may wonder why making this available to non-modified, permanent objects -> reason is that it was initially designed to make it possible to "release" objects in ECs, e.g. to keep the number of held objects under a certain limit: releasing an object also release memory (from db caches, mostly). However it's applicable to modified objects, as shown in the test. - About the propagation of reset up the EC hierarchy: it's not done and this is a problem. Most probably, the rest of an object wil also reset it in its parents. But even then, this is only a proposal for the default behaviour, and one ec should be able to provide its own response to the refault notification coming from a parent, for example through a delegate. NB: however to test it w/ modified objects the following lines in EC.refaultObject() should be disabled --my fault: if gid in self._pendingUpdatedObjects+self._updatedObjects: raise ValueError, 'Cannot refault a modified object' >=20=20=20=20=20 > the other comment is (I think this is the update you mention above): >=20=20=20=20=20 > --- paste --- > Note: it can be safely applied on modified objects given that no > relationships have been modified (such a situation has not been tested > at all). > --- paste --- >=20 > I'll try to make some tests in both cases. >=20=20=20=20=20 > it is interesting to note that most of this patch is already in the > slice_n_sort patch. is that an error? shouldn't this other one depend on > the first one, so applying both doesn't choke? You're right! I was not even able to find a difference, it's completely included in patch #892454... I have several tests configurations here and it seems that one got integrated in the other. Thanks for noticing, I'll add a note to the patches'page. -- S=E9bastien. |