modeling-users Mailing List for Object-Relational Bridge for python (Page 17)
Status: Abandoned
Brought to you by:
sbigaret
You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(2) |
Sep
(3) |
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(19) |
Feb
(55) |
Mar
(54) |
Apr
(48) |
May
(41) |
Jun
(40) |
Jul
(156) |
Aug
(56) |
Sep
(90) |
Oct
(14) |
Nov
(41) |
Dec
(32) |
2004 |
Jan
(6) |
Feb
(57) |
Mar
(38) |
Apr
(23) |
May
(3) |
Jun
(40) |
Jul
(39) |
Aug
(82) |
Sep
(31) |
Oct
(14) |
Nov
|
Dec
(9) |
2005 |
Jan
|
Feb
(4) |
Mar
(13) |
Apr
|
May
(5) |
Jun
(2) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2006 |
Jan
(1) |
Feb
(1) |
Mar
(9) |
Apr
(1) |
May
|
Jun
(1) |
Jul
(5) |
Aug
|
Sep
(5) |
Oct
(1) |
Nov
|
Dec
|
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
(1) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(4) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Mario R. <ma...@ru...> - 2003-12-21 19:27:10
|
>> I would like to use custom FixedPoint values for an attribute of an >> object. >> So, I do as the example in Chapter 9 of the userguide suggests... so >> I define >> the "private" methods obj._setX(val) and obj._getX(). However, when >> the >> client code calls the corresponding public setX and getX methods, the >> private ones are never called! Any ideas what I may be missing out on? >> I am using 0.9-pre-16 of modeling plus bug862182.patch >> (no other patches I think). > > Well, I think there should be something obscure in the doc. if it made > you think that public methods call the corresponding private ones. It > is > definitely not the case (at least by default, nothing prevents you from > doing this). > > Private accessors (as searched by KeyValueCoding.storedValueForKey) > are the only one used by the framework. That's why they can be used, > in particular, to define transformation from sql types to custom > types. > > Without more info. I cannot really tell why this bothers you so much :) Hmmn, I have mis-assumed ;(( It bothers me because it does not do what I expect! If I add the following "balance" methods to a MyCustomObject class: def _setBalance(self, value): if value is None: self._balance=None else: self._balance = FixedPoint(value, 6) def _getBalance(self): if not self._balance: return None else: return str(self._balance) Then, in an interactive session: >>> a = MyCustomObject() >>> a.getBalance() '' >>> a.setBalance(FixedPoint('123.456')) >>> a.getBalance() FixedPoint('123.46', 2) >>> Thus, on first getBalance() I should get None. And on second getBalance() I should get a FixedPoint of pecision 6 not 2. I am missing something! It is late weekend, and I stop! Cheers, mario |
From: Sebastien B. <sbi...@us...> - 2003-12-21 19:07:19
|
Hi, Mario Ruggier <ma...@ru...> writes: > Hello! >=20 > I would like to use custom FixedPoint values for an attribute of an obje= ct. > So, I do as the example in Chapter 9 of the userguide suggests... so I d= efine > the "private" methods obj._setX(val) and obj._getX(). However, when the > client code calls the corresponding public setX and getX methods, the > private ones are never called! Any ideas what I may be missing out on? > I am using 0.9-pre-16 of modeling plus bug862182.patch > (no other patches I think). Well, I think there should be something obscure in the doc. if it made you think that public methods call the corresponding private ones. It is definitely not the case (at least by default, nothing prevents you from doing this). Private accessors (as searched by KeyValueCoding.storedValueForKey) are the only one used by the framework. That's why they can be used, in particular, to define transformation from sql types to custom types. Without more info. I cannot really tell why this bothers you so much :) > Another small point: the example _get method in: > <http://modeling.sourceforge.net/UserGuide/attribute-custom-type- > example.html> > should surely read: >=20 > if not self._price: > return None >=20 > as opposed to (if self._price: ... ) Absolutely, thanks! -- S=E9bastien. |
From: Mario R. <ma...@ru...> - 2003-12-21 17:58:35
|
Hello! I would like to use custom FixedPoint values for an attribute of an object. So, I do as the example in Chapter 9 of the userguide suggests... so I define the "private" methods obj._setX(val) and obj._getX(). However, when the client code calls the corresponding public setX and getX methods, the private ones are never called! Any ideas what I may be missing out on? I am using 0.9-pre-16 of modeling plus bug862182.patch (no other patches I think). Another small point: the example _get method in: <http://modeling.sourceforge.net/UserGuide/attribute-custom-type- example.html> should surely read: if not self._price: return None as opposed to (if self._price: ... ) Cheers, mario |
From: Sebastien B. <sbi...@us...> - 2003-12-20 16:14:09
|
Ezra E. <sf-...@pr...> wrote: > Hi, >=20 > Looking through the docs it seems that the modeling framework makes so= me > stronger assumptions about how entities are mapped to database result sets > than one finds in EOF. In particular, is there a way to map objects to t= he > results of stored procedures? (Again, how hard would it be for an EOF-sa= vvy > developer to add?) Well, you're right, we're making stronger assumptions than in EOF. Unfortunately, here again, I've no experience at all w/ stored proc. so it's hard to tell how much time it would take, just because I cannot foresse any possible difficulty that may arise. However, it's also no clear to me what you really mean by <<mapping objects to the results of stored proc.>>. Does this mean that such entities will be read-only, or should there also be some procedures to insert & delete? BTW, if I assume that stored procedure is not a too ugly beast and that, from a python db-adaptor point of view it does not differ a lot from the standard SQL manipulating selects/inserts/deletes (sounds like a middle-to-strong assumption, but never mind), then I guess this won't be to hard to implement. MDL.Entity should probably store the stored procedures to be used. Having a quick look at the code, I think that this info. about stored proc. to use can be used, at best, during the DBContext's performChanges() phase, when AdaptorOperation are built from DatabaseOperation. Does this answers the question? Probably not fully ;) Again, please fill a RFE at sourceforge if it's something you're likely to need quickly. But the story is that I have the feeling that it should not be a difficult thing to add to the framework. Last, I'd say as usual that, if you have small toy-examples that we can play with, that would be great --at least for me who never played w/ any stored proc. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-12-20 15:58:40
|
Ezra E. <sf-...@pr...> wrote: > While we're at it, does the modeling.py framework support Postgres array > columns? If not, any sense of how hard it would be for an EOF-experienced > developer to add this? I did not know anything about postgresql column arrays before i read your mail :/ so it's hard for me to establish a precise timeframe. To all: shortly put, array columns allows a table's column to receive arrays of datas. For more you can refer to: http://www.postgresql.org/docs/aw_pgsql_book/node95.html http://www.postgresql.org/docs/7.3/interactive/arrays.html http://www.postgresql.org/docs/7.4/interactive/arrays.html Some quick investigations showed me that among the three supported python-db adaptor for postgresql, i.e. psycopg, pgdb and pyPgSQL, only the latter supports arrays; the first two do not and simply return strings (NB: these preliminary tests were made w/ postgresql 7.3 and the pyadaptors were compiled & linked w/ pg7.3 headers & lib., and I've no idea on whether they behave the same w/ pg7.4). Does it mean the framework will need to handle the array types by itself when using psycopg or pgdb? I'm not sure I like that... If you want to investigate how hard it can be to add support for this, I suggest you first try to consider them as 'custom types' and design the code for supporting them. -- http://modeling.sourceforge.net/UserGuide/attribute-custom-type.html Agreed, this is only a first step towards integration of this in the framework, but at least if you need this you will probably get it really quickly this way. BTW I've discovered that pyPgSQL has a useful fonction that might be handy: PgArray._quote() impl. in PgSQL._handleArray(). Are you already using pg array columns w/ python? With which pyadaptor? I think I also read that pg arrays are somehow an extension of SQL99 array feature, do you have any hint about this? Is there any equivalent in mysql, oracle, sqlite? Last question: if you already manipulated array columns, can you tell if some non-existing features would possibly be desirable/required in fetch qualifiers? -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-12-20 15:50:33
|
Hi, Ezra E. <sf-...@pr...> wrote: > Reading section 2.3.2.1 of the documentation (nice docs, by the way!) I > see that support has not yet been added for multi-attribute primary keys. > Is there an intention to add that? If so is there a time frame? There is no ETA for this feature, but there is an intention to add that, yes, the first time someone really needs it ;) Apart from some quick-and-dirty code that probably slipped through my fingers and gained access to the cvs main trunk, the framework normally does not assume that an entity has only one PK attribute. Since you suggest that you're an experienced EOF-user here are some more details: the implementation of such a feature implies: - creating the delegate interface for the DBContext which in turn would implement databaseContextNewPrimaryKey(). - have DBContext.prepareForSaveWithCoordinator() ask the delegate for a value before the AdaptorChannel gets a chance to provide its own primaryKeysForNewRowsWithEntity() NB: The delegation code is already ready to be used, even if not used yet http://modeling.sf.net/API/Modeling-API/public/Modeling.delegation-module.h= tml Last, we'll need to test that relationships from/to entities w/ compound pks behave as expected. Please fill in a RFE if you feel like you need this: this public list of requests is the best mean to prevent me from forgetting about users' requests! -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-12-20 15:35:53
|
Hi all, Some time ago I warned you about a bug, affecting generated database schemas for all adaptors, that was causing exceptions at saveChanges() time while the data committed are absolutely valid. In addition, this bug can possibly lead to *data loss* when the framework is used w/ Postgresql and psycopg --because of an other bug found in psycopg, fixed in v1.1.11 (upgrade is strongly recommended). The bug is now fixed, but still, db schema generated by the framework needs to be fixed by hand. A script has been made to help you determine whether the db-schema derived from your model(s) are affected by the bug. When it is the case, the script also indicates what should be done for fixing the problem. You'll find all the details here: http://modeling.sourceforge.net/bugs/bug861048.html (The reason why there is a specific page for that bug is that it is one the rare bugs that cannot be simply fixed by a patch against the framework itself) Sorry for any inconvenience, -- S=E9bastien. Initial announce: https://sf.net/mailarchive/forum.php?thread_id=3D3559235&forum_id=3D10674 SF Bug ticket: https://sf.net/tracker/index.php?func=3Ddetail&aid=3D861048&group_id=3D5893= 5&atid=3D489335 |
From: Ezra E. <eep...@pr...> - 2003-12-19 07:55:02
|
Hi, Looking through the docs it seems that the modeling framework makes some stronger assumptions about how entities are mapped to database result sets than one finds in EOF. In particular, is there a way to map objects to the results of stored procedures? (Again, how hard would it be for an EOF-savvy developer to add?) Thanks, Ezra E. |
From: ee <sf-...@pr...> - 2003-12-19 06:52:52
|
While we're at it, does the modeling.py framework support Postgres array columns? If not, any sense of how hard it would be for an EOF-experienced developer to add this? Thx, Ezra E. |
From: ee <sf-...@pr...> - 2003-12-19 05:38:42
|
Hi, Reading section 2.3.2.1 of the documentation (nice docs, by the way!) I see that support has not yet been added for multi-attribute primary keys. Is there an intention to add that? If so is there a time frame? Thanks, Ezra E. |
From: Sebastien B. <sbi...@us...> - 2003-12-12 17:11:26
|
Hi, Not much time to comment, just the announce: > I created bug ticket #857803 for that, where you'll also find the > patch John offered and which solves the problem for mysql 4.0+ >=20 > https://sf.net/tracker/index.php?func=3Ddetail&aid=3D857803&group_id=3D58= 935&atid=3D489335 I've submitted that will probably the definitive fix there. Note that if you're using mysql server v4.0 or higher, and your MySQLdb.get_version_info= () returns 3.23 (just like mine :), you can set MDL_MYSQL_SERVER_VERSION to '4= .0' --if not, you won't get any JOIN keyword, just plain SQL89 statements, so that's nothing really bad. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-12-10 19:44:58
|
Hi John and all, I wish I had more time for this now :/ BTW, I just wanted to say thank you John for the tests and the example. They reveal that the SQL generated for MySQL is *incorrect* for such qualifiers. I created bug ticket #857803 for that, where you'll also find the patch John offered and which solves the problem for mysql 4.0+ https://sf.net/tracker/index.php?func=3Ddetail&aid=3D857803&group_id=3D5893= 5&atid=3D489335 When a patch is available solving the problem for mysql 3.23 as well it will be put there and announced here. I'm afraid there is no working solution for mysql 3.23 using the JOIN keyword (if there is one, I couldnt find it) for such qualifiers, so we'll need to forget about the JOIN keyword for mysql 3.23 and use explicit joints, i.e. w/ no join kw. but w/ the join condition in the where clause (as this is already done for oracle8i). mysql_server_version() will probably also check for an env. variable before checking MySQLdb.get_client_info(), since it seems that MySQLdb can be built w/ a 3.23 compatible library while speaking w/ a 4.0 server (I have an example at home:) -- S=E9bastien. John Georgiadis <ig...@do...> writes: > Unpatched and patched both succeed. However if I switch the last test > from: > '(age<100) AND pygmalion.books.title like "G*"' > To: > '(age<100) AND ((books.title like "G*") OR (pygmalion.books.title like > "G*"))' >=20 > Then the unpatched version fails, while the patched succeeds. I think, > this is related to two joins (Writer.books & Writer.pygmalion) going to > different directions. Below is the generated SQL in both cases >=20 > SELECT DISTINCT t0.ID, t0.LAST_NAME, t0.FIRST_NAME, t0.AGE, > t0.FK_WRITER_ID, t0.BIRTHDAY FROM BOOK t1 INNER JOIN WRITER t0 ON ( > t0.ID=3Dt1.FK_WRITER_ID ) ( BOOK t3 INNER JOIN WRITER t2 ON ( > t2.ID=3Dt3.FK_WRITER_ID ) ) INNER JOIN WRITER t0 ON ( > t0.FK_WRITER_ID=3Dt2.ID ) WHERE (t0.AGE < 100 AND (t1.title LIKE BINARY > 'G%' OR t3.title LIKE BINARY 'G%')) > You have an error in your SQL syntax. Check the manual that corresponds > to your MySQL server version for the right syntax to use near '( BOOK t3 > INNER JOIN WRITER t2 ON ( t2.ID=3Dt3.FK_WRITER_ID ) ) >=20 > SELECT DISTINCT t0.ID, t0.LAST_NAME, t0.FIRST_NAME, t0.AGE, > t0.FK_WRITER_ID, t0.BIRTHDAY FROM WRITER t0 INNER JOIN BOOK t1 ON > t0.ID=3Dt1.FK_WRITER_ID INNER JOIN ( WRITER t2 INNER JOIN BOOK t3 ON > t2.ID=3Dt3.FK_WRITER_ID ) ON t0.FK_WRITER_ID=3Dt2.ID WHERE (t0.AGE < 100 > AND (t1.title LIKE BINARY 'G%' OR t3.title LIKE BINARY 'G%')) |
From: John G. <ig...@do...> - 2003-12-09 12:19:19
|
Unpatched and patched both succeed. However if I switch the last test from: '(age<100) AND pygmalion.books.title like "G*"' To: '(age<100) AND ((books.title like "G*") OR (pygmalion.books.title like "G*"))' Then the unpatched version fails, while the patched succeeds. I think, this is related to two joins (Writer.books & Writer.pygmalion) going to different directions. Below is the generated SQL in both cases SELECT DISTINCT t0.ID, t0.LAST_NAME, t0.FIRST_NAME, t0.AGE, t0.FK_WRITER_ID, t0.BIRTHDAY FROM BOOK t1 INNER JOIN WRITER t0 ON ( t0.ID=3Dt1.FK_WRITER_ID ) ( BOOK t3 INNER JOIN WRITER t2 ON ( t2.ID=3Dt3.FK_WRITER_ID ) ) INNER JOIN WRITER t0 ON ( t0.FK_WRITER_ID=3Dt2.ID ) WHERE (t0.AGE < 100 AND (t1.title LIKE BINARY 'G%' OR t3.title LIKE BINARY 'G%')) You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '( BOOK t3 INNER JOIN WRITER t2 ON ( t2.ID=3Dt3.FK_WRITER_ID ) ) SELECT DISTINCT t0.ID, t0.LAST_NAME, t0.FIRST_NAME, t0.AGE, t0.FK_WRITER_ID, t0.BIRTHDAY FROM WRITER t0 INNER JOIN BOOK t1 ON t0.ID=3Dt1.FK_WRITER_ID INNER JOIN ( WRITER t2 INNER JOIN BOOK t3 ON t2.ID=3Dt3.FK_WRITER_ID ) ON t0.FK_WRITER_ID=3Dt2.ID WHERE (t0.AGE < 100 AND (t1.title LIKE BINARY 'G%' OR t3.title LIKE BINARY 'G%')) On Mon, 8 Dec 2003, Sebastien Bigaret wrote: > > Hi, > > Thanks for the report. I've searched the mysql-site for about half an > hour but couldn't find any hints on when the change happened. Do you > (or anyone here) have any clue? > > Second, could you possibly confirm that the test >test_11_allQualifierOperators() in test_EditingContext_Global.py fails >when you patch is /not/ applied, and succeeds when it is applied? If it >does not, then I'll need to write a new one revealing that bug. > > Given that this particular test behaves as expected, your patch will > be applied as-is and integrated to the main trunk. Thanks again for > reporting. > >-- S=E9bastien. > > >John Georgiadis <ig...@do...> wrote: >> Hi Sebastian, >> >> I get a syntax error from MySQL-4.0.11 when using nested JOINS created b= y >> MySQLAdaptorLayer.MySQLExpression._addTableJoinsForAlias(). If I switch = to >> Modeling.SQLExpression._addTableJoinsForAlias(), the problem is gone. >> >> The following patch does this for mysql version >=3D 4.0.11. If anyone c= an >> confirm this for an older version of MySQL, then feel free to lower the >> version numbers in the tuple. > > |
From: Mario R. <ma...@ru...> - 2003-12-08 17:44:21
|
On Lundi, d=E9c 8, 2003, at 17:45 Europe/Zurich, Sebastien Bigaret = wrote: > Mario Ruggier <ma...@ru...> wrote: >> Hello, >> >>>> - how to best incorporate a constraint that a (non-primary, string) >>>> attribute value should be unique ? >>> >>> Well, there's no way to tell the framework to enforce that, my >>> suggestion would be to alter the db-schema to tell the database = about >>> this, e.g.:: >>> >>> ALTER TABLE BOOK ADD CONSTRAINT unique_book_title UNIQUE(TITLE); >> >> This seems simple enough, and would be very acceptable -- except, >> that sqlite does not support alter table directly unfortunately, so = it >> becomes more messy in that case. See: =20 >> <http://www.sqlite.org/omitted.html> > > Right, then you need to dump the db-schema, modify it, then give it to > sqlite. Messy, agreed. Seems to be a good reason. Great, thanks. >>> Note that we can maybe consider adding a 'unique' property to >>> attributes, but then, this won't be enforced by the framework itself >>> (because validation would require fetching all values such a field =20= >>> and >>> comparing) but by the database. But at least the generated db schema >>> could take this into account, and errors would be appropriately =20 >>> raised >>> at commit time by the database. If you really feel like you need =20 >>> this, >>> please fill in a RFE. >> >> Maybe framework validation of unique need not be that expensive. >> How about doing a raw count for 'entity where unikatt=3D"val"'? such >> requests are superquick. > > You're absolutely right, sometimes I'd better think before writing :) Or maybe, don't think too much ;) In any case, I do not know whether doing a count will prove to be fast enough. >> However if you would need to do this 100's >> of times per validation, then it will add up of course. >> Do you have an idea whether this might be feasible? >> >> Even if not checked by the framework, I would be in favour of adding >> a unique property to attributes. The priority here is to protect the =20= >> integrity >> of the data. If the error message received by the client is not =20 >> cryptic, then >> so much the better.... So, I think I will fill out an RFE. > > We're okay on this, I'm convinced. Not sure yet whether the framework =20= > will > check it and leave this to the db, buit we can add such a property to > attributes. Great, excellent, thank you! No rush though. >>>> - how to best handle enumeration attributes ? >>> >>> I'd say, add your own validation logic for the attribute and/or =20= >>> check >>> for valid values in setters. >> >> Hmmn. I do not like that so much (and that's not only because I'm =20 >> lazy ;). >> This seems to be a little requested feature, so priority shuold be =20= >> kept >> low -- but, what do you think of an 'isEnumeration=3D[ ... ]' = attribute =20 >> field? >> The values inside the list must respect the type of the attribute =20 >> itself? >> Another RFE ;-? > > Sorry, I don't really understand why you don't like it. This only = means > writing a method for checking the values, and calling it in the setter = =20 > and in > the validation method. Is that such a big deal? Well, because conceptually constraints on the value of an attribute are really part of the model. Keeping this information separate from the model is unnatural, and may lead to "forgetfulness bugs" and other =20 annoyances. Plus, ideally, the generated code for custom classes should be 100% =20 automatic... But, maybe an isEnumeration property is not the best solution. You have a description of how to add automatic handling of custom types in the user's guide. Would this be applicable, treating an enumeration =20= as a special type? (Would still have the disadvantage of requiring to modify =20= the generated python classes... ). >>>> - how to best handle the single quote character when writing out >>>> string values ? (unescaped gives error for sqlite) >>> >>> Hmm, strange, I need to check that. This is a bug, I do not know =20 >>> whether >>> this affects other adaptors as well --in any case you can fill in a =20= >>> bug >>> report for this one, thanks for reporting. >> >> OK, thanks. > > This is bug #855257 right? Yes, it is. > In that case, it's another bug for the qualifier > parser, because the problem is that this string: > >>>> " attname =3D '%s' " %("abc'def") > " attname =3D 'abc'def' " > > is a complete non-sense and should be detected as such. BTW, this =20 > reminds me > of this RFE: > https://sourceforge.net/tracker/=20 > index.php?func=3Ddetail&aid=3D804243&group_id=3D58935&atid=3D489338 > > requesting for secure quoting of qualifiers' parameters --it seems =20= > to me > that both subjects are somehow connected. Yes, they seem to be the same thing... Generalizing, whether to single quote a value or not when constructing =20= the SQL WHERE clause should be detected automatically from the information in the =20 model? Well, the mechanism we had before for building fetchSpecifications and =20= Qualfiers did this to some extent, or am I wrong? We should anyway not go around =20= in circles. The current simplicity of fetch is very nice. Just need to make =20 buildling qualifiers easier... I use a dict that I pass to a custom function, to build the =20= ANDed WHERE clause, but need to generalize to OR, and other comparison operators other than =20= equal. In any case, the above bug is a serious problem, and would consider it =20= high priority. BTW, another question: Can you express a condition such as attrib1 =3D=3D attrib2 on a given =20= entity? > > Cheers, > > -- S=E9bastien. > |
From: Sebastien B. <sbi...@us...> - 2003-12-08 16:53:52
|
Hi, Thanks for the report. I've searched the mysql-site for about half an hour but couldn't find any hints on when the change happened. Do you (or anyone here) have any clue? Second, could you possibly confirm that the test test_11_allQualifierOperators() in test_EditingContext_Global.py fails when you patch is /not/ applied, and succeeds when it is applied? If it does not, then I'll need to write a new one revealing that bug. Given that this particular test behaves as expected, your patch will be applied as-is and integrated to the main trunk. Thanks again for reporting. -- S=E9bastien. John Georgiadis <ig...@do...> wrote: > Hi Sebastian, >=20 > I get a syntax error from MySQL-4.0.11 when using nested JOINS created by > MySQLAdaptorLayer.MySQLExpression._addTableJoinsForAlias(). If I switch to > Modeling.SQLExpression._addTableJoinsForAlias(), the problem is gone. >=20 > The following patch does this for mysql version >=3D 4.0.11. If anyone can > confirm this for an older version of MySQL, then feel free to lower the > version numbers in the tuple. |
From: Sebastien B. <sbi...@us...> - 2003-12-08 16:42:50
|
Hi, Mario Ruggier <ma...@ru...> wrote: > Hello, >=20 > >> - how to best incorporate a constraint that a (non-primary, string) > >> attribute value should be unique ? > > > > Well, there's no way to tell the framework to enforce that, my > > suggestion would be to alter the db-schema to tell the database about > > this, e.g.:: > > > > ALTER TABLE BOOK ADD CONSTRAINT unique_book_title UNIQUE(TITLE); >=20 > This seems simple enough, and would be very acceptable -- except, > that sqlite does not support alter table directly unfortunately, so it > becomes more messy in that case. See: <http://www.sqlite.org/omitted.html> Right, then you need to dump the db-schema, modify it, then give it to sqlite. Messy, agreed. Seems to be a good reason. > > Note that we can maybe consider adding a 'unique' property to > > attributes, but then, this won't be enforced by the framework itself > > (because validation would require fetching all values such a field and > > comparing) but by the database. But at least the generated db schema > > could take this into account, and errors would be appropriately raised > > at commit time by the database. If you really feel like you need this, > > please fill in a RFE. >=20 > Maybe framework navigation of unique need not be that expensive. > How about doing a raw count for 'entity where unikatt=3D"val"'? such > requests are superquick.=20 You're absolutely right, sometimes I'd better think before writing :) > However if you would need to do this 100's > of times per validation, then it will add up of course. > Do you have an idea whether this might be feasible? >=20 > Even if not checked by the framework, I would be in favour of adding > a unique property to attributes. The priority here is to protect the inte= grity > of the data. If the error message received by the client is not cryptic, = then > so much the better.... So, I think I will fill out an RFE. We're okay on this, I'm convinced. Not sure yet whether the framework will check it and leave this to the db, buit we can add such a property to attributes. >=20 > >> - how to best handle enumeration attributes ? > > > > I'd say, add your own validation logic for the attribute and/or check > > for valid values in setters. >=20 > Hmmn. I do not like that so much (and that's not only because I'm lazy ;). > This seems to be a little requested feature, so priority shuold be kept > low -- but, what do you think of an 'isEnumeration=3D[ ... ]' attribute f= ield? > The values inside the list must respect the type of the attribute itself? > Another RFE ;-? Sorry, I don't really understand why you don't like it. This only means writing a method for checking the values, and calling it in the setter and = in the validation method. Is that such a big deal? > >> - how to best handle the single quote character when writing out > >> string values ? (unescaped gives error for sqlite) > > > > Hmm, strange, I need to check that. This is a bug, I do not know whether > > this affects other adaptors as well --in any case you can fill in a bug > > report for this one, thanks for reporting. >=20 > OK, thanks. This is bug #855257 right? In that case, it's another bug for the qualifier parser, because the problem is that this string: >>> " attname =3D '%s' " %("abc'def") " attname =3D 'abc'def' " is a complete non-sense and should be detected as such. BTW, this reminds me of this RFE: https://sourceforge.net/tracker/index.php?func=3Ddetail&aid=3D804243&group_= id=3D58935&atid=3D489338 requesting for secure quoting of qualifiers' parameters --it seems to me that both subjects are somehow connected. Cheers, -- S=E9bastien. |
From: John G. <ig...@do...> - 2003-12-08 14:01:55
|
Hi, This is a 2nd try on a patch sent last week about handling boolean values in the xml model generated with python 2.3. It is less intrusive than the previous and it doesn't use the bool() built-in, so it runs under python 2.1 as well. diff -urN --exclude=Python_bricks Modeling.orig/Attribute.py Modeling/Attribute.py --- Modeling.orig/Attribute.py 2003-08-30 20:22:56.000000000 +0300 +++ Modeling/Attribute.py 2003-12-08 13:29:19.000000000 +0200 @@ -572,6 +572,8 @@ attrType=self.xmlAttributeType(attributeName) set=self.xmlSetAttribute(attributeName) if attrType=='string': value=unicodeToStr(value, encoding) + elif attrType=='number': value=int(value) + elif attrType=='bool': value=int(value) set(value) def getXMLDOM(self, doc=None, parentNode=None, encoding='iso-8859-1'): @@ -596,7 +598,9 @@ exportAttrDict=self.xmlAttributesDict(select=1) for attr in exportAttrDict.keys(): + attrType=self.xmlAttributeType(attr) value=self.xmlGetAttribute(attr)() + if attrType=='bool': value=int(value) value=strToUnicode(str(value), encoding) node.setAttribute(attr, value) @@ -634,10 +638,10 @@ 'externalType' : ('string', self.setExternalType, self.externalType), - 'isClassProperty' : ('string', + 'isClassProperty' : ('bool', self.setIsClassProperty, self.isClassProperty), - 'isRequired' : ('string', + 'isRequired' : ('bool', self.setIsRequired, self.isRequired), # defaultValue must be loaded AFTER type is set, or we will get the @@ -659,7 +663,7 @@ setType(aType=aType, check=0), self.type), - 'isFlattened' : ('string', + 'isFlattened' : ('bool', self.setIsFlattened, self.isFlattened), 'width' : ('string', diff -urN --exclude=Python_bricks Modeling.orig/Entity.py Modeling/Entity.py --- Modeling.orig/Entity.py 2003-10-04 15:29:43.000000000 +0300 +++ Modeling/Entity.py 2003-12-08 13:31:19.000000000 +0200 @@ -1278,6 +1278,8 @@ attrType=self.xmlAttributeType(attributeName) set=self.xmlSetAttribute(attributeName) if attrType=='string': value=unicodeToStr(value, encoding) + elif attrType=='number': value=int(value) + elif attrType=='bool': value=int(value) set(value) if phase==1: @@ -1359,7 +1361,9 @@ exportAttrDict=self.xmlAttributesDict() for attr in exportAttrDict.keys(): + attrType=self.xmlAttributeType(attr) value=self.xmlGetAttribute(attr)() + if attrType=='bool': value=int(value) value=strToUnicode(str(value), encoding) node.setAttribute(attr, value) @@ -1405,10 +1409,10 @@ 'externalName': ( 'string', self.setExternalName, self.externalName ), - 'isReadOnly': ( 'string', + 'isReadOnly': ( 'bool', self.setReadOnly, self.isReadOnly ), - 'isAbstract': ( 'string', + 'isAbstract': ( 'bool', self.setIsAbstract, self.isAbstract ), 'moduleName': ( 'string', diff -urN --exclude=Python_bricks Modeling.orig/Relationship.py Modeling/Relationship.py --- Modeling.orig/Relationship.py 2003-07-28 10:18:59.000000000 +0300 +++ Modeling/Relationship.py 2003-12-08 13:34:29.000000000 +0200 @@ -252,6 +252,7 @@ set=self.xmlSetAttribute(attributeName) if attrType=='string': value=unicodeToStr(value, encoding) if attrType=='number': value=int(value) + elif attrType=='bool': value=int(value) set(value) return @@ -278,7 +279,9 @@ # exportAttrDict=self.xmlAttributesDict() for attr in exportAttrDict.keys(): + attrType=self.xmlAttributeType(attr) value=self.xmlGetAttribute(attr)() + if attrType=='bool': value=int(value) value=strToUnicode(str(value), encoding) node.setAttribute(attr, value) @@ -303,7 +306,7 @@ 'displayLabel' : ('string', self.setDisplayLabel, self.displayLabel), - 'isClassProperty' : ('number', + 'isClassProperty' : ('bool', self.setIsClassProperty, self.isClassProperty), 'multiplicityLowerBound': ('number', |
From: John G. <ig...@do...> - 2003-12-07 16:55:34
|
Hi Sebastian, I get a syntax error from MySQL-4.0.11 when using nested JOINS created by MySQLAdaptorLayer.MySQLExpression._addTableJoinsForAlias(). If I switch to Modeling.SQLExpression._addTableJoinsForAlias(), the problem is gone. The following patch does this for mysql version >= 4.0.11. If anyone can confirm this for an older version of MySQL, then feel free to lower the version numbers in the tuple. diff -urN --exclude=Python_bricks Modeling.orig/DatabaseAdaptors/MySQLAdaptorLayer/MySQLSQLExpression.py Modeling/DatabaseAdaptors/MySQLAdaptorLayer/MySQLSQLExpression.py --- Modeling.orig/DatabaseAdaptors/MySQLAdaptorLayer/MySQLSQLExpression.py 2003-08-10 14:59:13.000000000 +0300 +++ Modeling/DatabaseAdaptors/MySQLAdaptorLayer/MySQLSQLExpression.py 2003-12-07 18:14:53.000000000 +0200 @@ -33,6 +33,7 @@ __version__='$Revision: 1.7 $'[11:-2] +from Modeling.DatabaseAdaptors.MySQLAdaptorLayer.mysql_utils import * from Modeling.SQLExpression import SQLExpression, DateType, CharacterType from Modeling.logging import trace import string @@ -141,6 +142,10 @@ https://sourceforge.net/tracker/index.php?func=detail&aid=614261&group_id=58935&atid=489335 """ + version = mysql_server_version() + if version[:3] >= (4,0,11): + return SQLExpression._addTableJoinsForAlias(self, alias, str) + trace('alias: %s / str: %s'%(alias, str)) relPaths=self._internals.relPathsComingFromAlias(alias) aliases=map(lambda rp, self=self: self._internals.aliasForRelPath(rp), diff -urN --exclude=Python_bricks Modeling.orig/DatabaseAdaptors/MySQLAdaptorLayer/mysql_utils.py Modeling/DatabaseAdaptors/MySQLAdaptorLayer/mysql_utils.py --- Modeling.orig/DatabaseAdaptors/MySQLAdaptorLayer/mysql_utils.py 1970-01-01 02:00:00.000000000 +0200 +++ Modeling/DatabaseAdaptors/MySQLAdaptorLayer/mysql_utils.py 2003-12-07 18:07:52.000000000 +0200 @@ -0,0 +1,67 @@ +#----------------------------------------------------------------------------- +# +# Modeling Framework: an Object-Relational Bridge for python +# (c) 2001, 2002, 2003 Sebastien Bigaret +# +# This file is part of the Modeling Framework. +# +# The Modeling Framework 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. +# +# The Modeling Framework 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 the Modeling Framework; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +#----------------------------------------------------------------------------- + +import MySQLdb; + +""" +MySQL Adaptor Layer's utils + + Central point for determining MySQL specifics, like the version of the + mysql server in use. + + CVS information + + $Id$ + +""" + +__version__='$Revision$'[11:-2] + +import os + +def mysql_server_version(): + """ + Returns the version of the mysql server currently in use. It calls + MySQLdb.get_client_info(). + + Return value: + A 4-values tuple: (VERSION, PATCH_LEVEL, SUBLEVEL, EXTRA_VERSION) + E.g. (4,0,11,a-gamma) + + + """ + s = MySQLdb.get_client_info() + v_list = s.split('.', 3) + version = int(v_list[0]) + patch_level = int(v_list[1]) + s = v_list[2] + for i in range(len(s)): + if not s[i].isdigit(): + break + if i == 0: + sublevel = 0 + else: + sublevel = int(s[:i]) + extra_version = s[i:] + + return (version, patch_level, sublevel, extra_version) |
From: Mario R. <ma...@ru...> - 2003-12-06 07:58:13
|
Hello, >> - how to best incorporate a constraint that a (non-primary, string) >> attribute value should be unique ? > > Well, there's no way to tell the framework to enforce that, my > suggestion would be to alter the db-schema to tell the database about > this, e.g.:: > > ALTER TABLE BOOK ADD CONSTRAINT unique_book_title UNIQUE(TITLE); This seems simple enough, and would be very acceptable -- except, that sqlite does not support alter table directly unfortunately, so it becomes more messy in that case. See:=20 <http://www.sqlite.org/omitted.html> > Note that we can maybe consider adding a 'unique' property to > attributes, but then, this won't be enforced by the framework itself > (because validation would require fetching all values such a field and > comparing) but by the database. But at least the generated db schema > could take this into account, and errors would be appropriately raised > at commit time by the database. If you really feel like you need this, > please fill in a RFE. Maybe framework navigation of unique need not be that expensive. How about doing a raw count for 'entity where unikatt=3D"val"'? such requests are superquick. However if you would need to do this 100's of times per validation, then it will add up of course. Do you have an idea whether this might be feasible? Even if not checked by the framework, I would be in favour of adding a unique property to attributes. The priority here is to protect the=20 integrity of the data. If the error message received by the client is not=20 cryptic, then so much the better.... So, I think I will fill out an RFE. >> - how to best handle enumeration attributes ? > > I'd say, add your own validation logic for the attribute and/or = check > for valid values in setters. Hmmn. I do not like that so much (and that's not only because I'm lazy=20= ;). This seems to be a little requested feature, so priority shuold be kept low -- but, what do you think of an 'isEnumeration=3D[ ... ]' attribute=20= field? The values inside the list must respect the type of the attribute=20 itself? Another RFE ;-? >> - how to best handle the single quote character when writing out >> string values ? (unescaped gives error for sqlite) > > Hmm, strange, I need to check that. This is a bug, I do not know=20 > whether > this affects other adaptors as well --in any case you can fill in a = bug > report for this one, thanks for reporting. OK, thanks. Cheers, mario > -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-12-05 11:11:46
|
Mario Ruggier <ma...@ru...> wrote: > two small questions that I do not remember/find the answer for... > Can anyone remind me: > - how to best incorporate a constraint that a (non-primary, string) > attribute value should be unique ? Well, there's no way to tell the framework to enforce that, my suggestion would be to alter the db-schema to tell the database about this, e.g.:: ALTER TABLE BOOK ADD CONSTRAINT unique_book_title UNIQUE(TITLE); Note that we can maybe consider adding a 'unique' property to attributes, but then, this won't be enforced by the framework itself (because validation would require fetching all values such a field and comparing) but by the database. But at least the generated db schema could take this into account, and errors would be appropriately raised at commit time by the database. If you really feel like you need this, please fill in a RFE. > - how to best handle enumeration attributes ? I'd say, add your own validation logic for the attribute and/or check for valid values in setters. > - how to best handle the single quote character when writing out > string values ? (unescaped gives error for sqlite) Hmm, strange, I need to check that. This is a bug, I do not know whether this affects other adaptors as well --in any case you can fill in a bug report for this one, thanks for reporting. -- S=E9bastien. |
From: Mario R. <ma...@ru...> - 2003-12-05 10:37:48
|
Hi! > Hi Mario, > > My best bet is that the second model is not loaded at all. Keep in > mind that the model is loaded as soon as the package itself is = accessed > --ie. when the package's __init__.py is "traversed". Thus it's no > surprise that those two statements have the very same effect: > >>>>> from packone.EntInOne import EntInOne >>>>> from packone.EntInTwo import EntInTwo > > What happens here is probably that, since you generated the package w/ > the 1st model, the package's __init__.py only loads the 1st model. = When > you generated the code for the second model *in the same package*, > __init__.py already exists so it's not overwritten, nor it is changed. > > The relevant lines in __init__.py are: > > model=3DModel.searchModel("pymone", mydir, verbose=3D0) > if not model: > import warnings > warnings.warn("Couldn't load model pymone") > else: > ModelSet.defaultModelSet().addModel(model) > > they should probably be changed into something like: > > pymone=3DModel.searchModel("pymone", mydir, verbose=3D0) > pymtwo=3DModel.searchModel("pymtwo", mydir, verbose=3D0) > if not pymone or not pymtwo: > import warnings > warnings.warn("Couldn't load model(s) pymone and/or pymtwo") > else: > ModelSet.defaultModelSet().addModel(pymone) > ModelSet.defaultModelSet().addModel(pymtwo) > Ah, yes, this seems exactly right. I have switched to different packages for each model now, so to test it properly I need to go back to previous set-up (not sure which one I prefer now ;). However, I wonder if this code in __init__ can be parametrized somehow. All it needs as input is the list of models in the package. Maybe the list of models may be calculated by looking into the custom classes -- if model for this class is unknown yet, then it is added to the list... Otherwise, I could live with having to make such a modification=20 manually, but I would need to know about it (if I did know this last night I would have gained a few hours ;-) Thus, maybe at least an FAQ entry, such as: How can I automatically generate one package from several models? Thanks! mario > HTH, cheers, > > > -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-12-05 10:22:51
|
Hi Lukasz, <luk...@po...> wrote: > Hi >=20 > Thanks Sebastien for all advices. I use both optimization methods and the= re > are my results. They may be interesting. Given time is an average of 10 > measurments >=20 > Fetching one table 'Mothers' with 100 records and three tables related wi= th > it: > 0. Fetching table in "pure" PostgreSQL by psql: 0.025 seconds > With Modeling: > 1. Without any optimization: 14.20 seconds > 2. Setting permanent DB connection: 1.31 seconds > 3. Setting permanent DB connection and batchFetch 1.14 seconds > Now, its almost perfect [code snipped] Good to know it helped. BTW I'm very surprised by those 14.20s you get; I did not think things could go that slow, and it seems to me that this a very strong argument towards changing the default behaviour. If noone is against that, the next release will deprecate MDL_PERMANENT_DB_CONNECTION for MDL_TRANSIENT_DB_CONNECTION (or something alike), and the default will be: keep db connections opened. > > I should probably add this feature to the framework, it's been > > regularly asked. Do we want this in the next release? > > [...] > > PS: as I said it previously when I sent the first version of the patch, > > this is not the definitive user-friendly interface ;) There will > > probably be a more convenient method at the EditingContext level, > > something like ec.batchFetch(mothers, 'toProvince') e.g. >=20 > It's a VERY good idea. I think we can say we're going that way. > And a question about patches. How to include patch to the file. Now I just > copy the code from .patch file to .py file. It is propably some way to do= it > automaticaly with WinCVS, but I dont know how. I've no windows box at hand so I cannot help for sure, but maybe this link will be of some help: http://www.mail-archive.com/fo...@xm.../msg13872.html In any case you'll need to get a patch.exe. -- S=E9bastien. |
From: Sebastien B. <sbi...@us...> - 2003-12-05 10:12:34
|
Hi Mario, My best bet is that the second model is not loaded at all. Keep in mind that the model is loaded as soon as the package itself is accessed --ie. when the package's __init__.py is "traversed". Thus it's no surprise that those two statements have the very same effect: > >>> from packone.EntInOne import EntInOne > >>> from packone.EntInTwo import EntInTwo What happens here is probably that, since you generated the package w/ the 1st model, the package's __init__.py only loads the 1st model. When you generated the code for the second model *in the same package*, __init__.py already exists so it's not overwritten, nor it is changed. The relevant lines in __init__.py are: model=3DModel.searchModel("pymone", mydir, verbose=3D0) if not model: import warnings warnings.warn("Couldn't load model pymone") else: ModelSet.defaultModelSet().addModel(model) they should probably be changed into something like: pymone=3DModel.searchModel("pymone", mydir, verbose=3D0) pymtwo=3DModel.searchModel("pymtwo", mydir, verbose=3D0) if not pymone or not pymtwo: import warnings warnings.warn("Couldn't load model(s) pymone and/or pymtwo") else: ModelSet.defaultModelSet().addModel(pymone) ModelSet.defaultModelSet().addModel(pymtwo) HTH, cheers, -- S=E9bastien. Mario Ruggier <ma...@ru...> writes: > Hi, >=20 > I have two models that I am setting to be in the same > package, so I have something like: >=20 > model =3D Model('pymone', packageName=3D'packone', > connDict=3D{'database':'db_pymone.db'}) > model =3D Model('pymtwo', packageName=3D'packone', > connDict=3D{'database':'db_pymtwo.db'}) >=20 > in the respective pymodel files. All entity names are distinct > across both models. >=20 > The code generation into the same package, and the generation of > the two db's is fine. However, when I import entities form the second > model, what seems to happen is that the first model "becomes known" > but the entity (as it is in the other model) returns None... to clarify: >=20 > % python > [GCC Apple cpp-precomp 6.14] on darwin > Type "help", "copyright", "credits" or "license" for more information. > >>> from packone.EntInOne import EntInOne > >>> from Modeling.ModelSet import defaultModelSet > >>> ms =3D defaultModelSet() > >>> ms.modelsNames() > ['pymone'] > >>> ms.entityNamed('EntInOne') > <Modeling.Entity.Entity instance at 0x7d3140> > >>> from packone.EntInTwo import EntInTwo > >>> ms.modelsNames() > ['pymone'] > >>> ms.entityNamed('EntInTwo') > >>> ^D >=20 > if I only import an entity form the second model, the same thing happens: >=20 > % python > [GCC Apple cpp-precomp 6.14] on darwin > Type "help", "copyright", "credits" or "license" for more information. > >>> from packone.EntInTwo import EntInTwo > >>> from Modeling.ModelSet import defaultModelSet > >>> ms =3D defaultModelSet() > >>> ms.modelsNames() > ['pymone'] > >>> ms.entityNamed('EntInTwo') > >>> ^D >=20 > Am I abusing something here? > Let me know if I should put in a report. >=20 > Cheers, mario |
From: Sebastien B. <sbi...@us...> - 2003-12-05 10:04:13
|
Hi John, Sorry for the late answer. I still did not find the time to look at your patch, but I will, probably this week-end, and I'll then report here. It will probably need some adjustment before it is integrated into the main trunk since we still support py2.1 for now. Thanks a lot for sharing, -- S=E9bastien. John Georgiadis <ig...@do...> wrote: > Hi, >=20 > This is a patch to handle the differences between python 2.2 & 2.3 > regarding converting boolean values. It uses the bool() built-in, so I > think it won't work for versions of python < 2.2.1 >=20 > Boolean values such as isClassProperty & isAbstract are written as 0/1 > in 2.2 and True/False in 2.3. The model loads fine with either 2.2/2.3 > regardless of the version of python it was generated from. >=20 > I'm not familiar with the code base, so let me know if this breaks > something else. >=20 > cheers > john |
From: Mario R. <ma...@ru...> - 2003-12-05 06:58:56
|
Hi, I have two models that I am setting to be in the same package, so I have something like: model = Model('pymone', packageName='packone', connDict={'database':'db_pymone.db'}) model = Model('pymtwo', packageName='packone', connDict={'database':'db_pymtwo.db'}) in the respective pymodel files. All entity names are distinct across both models. The code generation into the same package, and the generation of the two db's is fine. However, when I import entities form the second model, what seems to happen is that the first model "becomes known" but the entity (as it is in the other model) returns None... to clarify: % python [GCC Apple cpp-precomp 6.14] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from packone.EntInOne import EntInOne >>> from Modeling.ModelSet import defaultModelSet >>> ms = defaultModelSet() >>> ms.modelsNames() ['pymone'] >>> ms.entityNamed('EntInOne') <Modeling.Entity.Entity instance at 0x7d3140> >>> from packone.EntInTwo import EntInTwo >>> ms.modelsNames() ['pymone'] >>> ms.entityNamed('EntInTwo') >>> ^D if I only import an entity form the second model, the same thing happens: % python [GCC Apple cpp-precomp 6.14] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from packone.EntInTwo import EntInTwo >>> from Modeling.ModelSet import defaultModelSet >>> ms = defaultModelSet() >>> ms.modelsNames() ['pymone'] >>> ms.entityNamed('EntInTwo') >>> ^D Am I abusing something here? Let me know if I should put in a report. Cheers, mario |