Thread: [SQLObject] A small patch around features I need
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: G. <fra...@cl...> - 2003-06-27 16:48:55
Attachments:
patch_SQLObject-Clarisys-20030627.diff
|
Clarisys patch for SQLOBject 0.3 author : Fran=E7ois Girault - fra...@cl... Updated : 27/06/03 ---------------------------------------------- INSTALL :=20 - download SQLObject 0.3 and untar it in a directory - put the patch file in this dir and then type 'patch -p0 < patch_filename' - enjoy ;-) ---------------------------------------------- 27/06/03 Changes : * id can now be passed at creation time when using db sequence is not appr= opriate myNewEntity =3D Entity.new(id=3D25) if Entity._idName is defined, you can also use this value as key to spe= cify the id : class Entity(SQLObject): _idName =3D 'code' ... myNewEntity =3D Entity.new(code=3D25) will work the same as previous de= claration * object ids can be alphanumerical type. Note that you MUST specify id at = creation time for the moment. Support for stored procedure to generate alph= anumerical ids will come in a close future ;-)=20 * relations between objects can use other fields than id (including alphan= umerical ones). In _join class attribute you can add these parameter to Joi= n children creation : * joinField let you specify the field to join within your class * otherField let you specify the field of the other table Note that the specified fields MUST be declared as alternateID ---------------------------------------------- Short sample .../... class Person(SQLObject): # Person table has a "serial" id field named 'id' in the table, but also a= n alphanumerical code to link to Occupation (in this context you would say = it's stupid but I need that in some cases) _columns =3D [ Col('code', alternateID=3DTrue), Col('firstname'), Col('las= tname') ] _joins =3D [ RelatedJoin('Occupation', joinField=3D'code', joinColumn=3D'p= erson_code', otherColumn=3D'occupation_code', intermediateTable=3D'person_o= ccupation') ] class Occupation(SQLObject): # code is alphanumerical _idName =3D 'code' _columns =3D [Col('label')] _joins =3D [RelatedJoin('Person', joinColumn=3D'person_code', otherColumn= =3D'occupation_code', otherField=3D'code', intermediateTable=3D'person_occu= pation')] occupation =3D Occupation.new(code=3D'WLK', label=3D'Walk in the mountain') # INSERT INTO occupation (label, code) VALUES ('Walk in the mountain', 'WLK= ') pers.addOccupation(occupation) # INSERT INTO person_occupation (person_code, occupation_code) VALUES ('ABC= ', 'WLK') .../... ---------------------------------------------- Limitation : * for Postgresql usage only due to modification in DBConnection, and I ha= ve no time to write & test with other DB (help welcome :) ). |
From: Ian B. <ia...@co...> - 2003-06-30 08:36:36
|
On Fri, 2003-06-27 at 11:42, Fran=E7ois Girault wrote: > Clarisys patch for SQLOBject 0.3 There's several things that have changed since 0.3 -- it would be helpful to do this against CVS instead. > * id can now be passed at creation time when using db sequence is not = appropriate >=20 > myNewEntity =3D Entity.new(id=3D25) >=20 > if Entity._idName is defined, you can also use this value as key to= specify the id : >=20 > class Entity(SQLObject): > _idName =3D 'code' > ... > myNewEntity =3D Entity.new(code=3D25) will work the same as previou= s declaration >=20 > * object ids can be alphanumerical type. Note that you MUST specify > id at creation time for the moment. Support for stored procedure to > generate alphanumerical ids will come in a close future ;-)=20 This seems fine -- I suspected the problem with non-integer ID's was mostly the occasional %i, which is most of what you've changed. It should be easy enough to add stored procedures, at the same time allowing differently-named sequences, or the current technique (that uses .lastrowid, I think, and in Postgres would actually work for most cases). Note that primary keys are still considered immutable -- this assumption exists in subtle ways in different parts of SQLObject, and the assumption is probably propagated to most people's applications. > * relations between objects can use other fields than id (including > alphanumerical ones). In _join class attribute you can add these > parameter to Join children creation : >=20 > * joinField let you specify the field to join within your class >=20 > * otherField let you specify the field of the other table >=20 > Note that the specified fields MUST be declared as alternateID That looks fine too, though I'm also planning to change (probably for 0.5) how the joins work, so that they create better SQL and create smarter objects than just lists. > * for Postgresql usage only due to modification in DBConnection, and > I have no time to write & test with other DB (help welcome :) ). It's very helpful if you include a unit test for any new features -- this is more important to me than supporting all the databases. A couple notes on the code itself: - func =3D eval('lambda self: self._SO_joinList[%i].performJoin(se= lf)' % index) + func =3D eval('lambda self: self._SO_joinList[%s].performJoin(se= lf)' % index) That %i isn't related to the ID. (in .new()): + inst._inst_id =3D None + if kw.has_key('id'): + inst._inst_id =3D kw['id'] + del kw['id'] + else: + if kw.has_key(inst._idName): + inst._inst_id =3D kw[inst._idName] + del kw[inst._idName] I think you're allowing people to use the database name of the column here, even though that's not allowed for any of the other columns. I don't think that should be allowed, nor should it be generalized to the rest of the columns -- it just creates ambiguity in your class usage. Anyway, I'd accept it except the _inst_id stuff, but I'd really like it to include a unit test (and a test which the current code wouldn't pass, of course :). It would be helpful if you can also redo it against CVS.=20 But the unit test is more important. I am repeating that for emphasis ;) Ian |
From: G. <fra...@cl...> - 2003-06-30 09:43:10
|
On 30 Jun 2003 03:37:30 -0500 Ian Bicking <ia...@co...> wrote: > On Fri, 2003-06-27 at 11:42, Fran=E7ois Girault wrote: > > Clarisys patch for SQLOBject 0.3 >=20 > There's several things that have changed since 0.3 -- it would be > helpful to do this against CVS instead. Ok, this is what i'm going to do now :) > > * for Postgresql usage only due to modification in DBConnection, and > > I have no time to write & test with other DB (help welcome :) ). >=20 > It's very helpful if you include a unit test for any new features -- > this is more important to me than supporting all the databases. Ok I'll try to include that. > A couple notes on the code itself: >=20 > - func =3D eval('lambda self: self._SO_joinList[%i].performJoin(se= lf)' % index) > + func =3D eval('lambda self: self._SO_joinList[%s].performJoin(se= lf)' % index) >=20 > That %i isn't related to the ID. Ok :) > (in .new()): > + inst._inst_id =3D None > + if kw.has_key('id'): > + inst._inst_id =3D kw['id'] > + del kw['id'] > + else: > + if kw.has_key(inst._idName): > + inst._inst_id =3D kw[inst._idName] > + del kw[inst._idName] >=20 > I think you're allowing people to use the database name of the column > here, even though that's not allowed for any of the other columns. I > don't think that should be allowed, nor should it be generalized to the > rest of the columns -- it just creates ambiguity in your class usage. Ok, I agree about ambiguity. So I'll only keep 'id' field name parameter. B= ut i have to store given id in the class otherwise I don't know how to give= this values as parameter in _SO_finishCreate() : id =3D self._connection.queryInsertID(self._table, self._idName, names, val= ues, self._inst_id) maybe an additionnal method to _connection would be the solution. > Anyway, I'd accept it except the _inst_id stuff, but I'd really like it > to include a unit test (and a test which the current code wouldn't pass, > of course :). It would be helpful if you can also redo it against CVS.=20 > But the unit test is more important. I am repeating that for emphasis > ;) Sir, yes, Sir ! ;) Fran=E7ois |
From: G. <fra...@cl...> - 2003-06-30 16:38:22
Attachments:
so04.diff
|
> > > > There's several things that have changed since 0.3 -- it would be > > helpful to do this against CVS instead. Done, see attached diff file > > It's very helpful if you include a unit test for any new features -- > > this is more important to me than supporting all the databases. I haven't yet include tests yet. I'm sorry about that, but I promise there will be some in the next days. ---------------------------------------------------------------------------------------- I also found a bug I hadn't with release 0.3 : on a table with multiple foreign keys from the same table, SQLObject raise a value at definition time, i.e while parsing the class : Traceback (most recent call last): File "BDDGen.py", line 75, in ? class Demande(SQLObject): File "/usr/lib/python2.2/site-packages/SQLObject/SQLObject.py", line 233, in __new__ newClass.addColumn(column) File "/usr/lib/python2.2/site-packages/SQLObject/SQLObject.py", line 503, in addColumn '_SO_class_%s' % column.foreignKey) File "/usr/lib/python2.2/site-packages/SQLObject/SQLObject.py", line 102, in addNeedSet getattr(obj, attr)(cls) File "/usr/lib/python2.2/site-packages/SQLObject/SQLObject.py", line 404, in __new__ val._init(id, connection, selectResults) File "/usr/lib/python2.2/site-packages/SQLObject/SQLObject.py", line 662, in _init selectResults = (connection or self._connection)._SO_selectOne(self, dbNames) File "/usr/lib/python2.2/site-packages/SQLObject/DBConnection.py", line 266, in _SO_selectOne return self.queryOne("SELECT %s FROM %s WHERE %s = %s" % File "/usr/lib/python2.2/site-packages/SQLObject/SQLBuilder.py", line 126, in sqlRepr raise ValueError, "Unknown SQL builtin type: %s for %s" % \ ValueError: Unknown SQL builtin type: <class 'SQLObject.SQLObject.MetaSQLObject'> for <class '__main__.Labo'> my cols are defined like this : Col('userID', dbName='user', foreignKey='Labo'), Col('couserID', dbName='couser', foreignKey='Labo'), I've to work around, but the only way I've found now is not to use the foreignKey :( |