Thread: [SQLObject] Patch for Cyclic References (with unit tests)
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: <jpa...@gm...> - 2005-10-04 14:29:17
Attachments:
cyclic.diff
test_cyclic_reference.py
|
Hi! Finally, I did write the unit tests for cyclic references. ;-) Attached is the patch and the test case. Some tests failed, but I'm not sure that was my fault. Unfortunately, I could not achieve my objective without changing the api for createTable and createTableSQL methods. createTable now returns a list of constraints and createTableSQL returns a tuple with the sql for table creation and the list of constraints. Also, a new abstract method was added to DBAPI class, in dbconnection.py, which needs to be implemented in database specific connections.I've tested with sqlite and postgres here. -- JP |
From: Oleg B. <ph...@ma...> - 2005-10-04 14:45:44
|
On Tue, Oct 04, 2005 at 09:48:16AM -0300, Jo?o Paulo Fernandes Farias wrote: > Unfortunately, I could not achieve my objective without changing the api for > createTable and createTableSQL methods. Hence it cannot be backported to 0.7.1. > + def createReferenceConstraint(self, soClass, col): > + assert 0, "Implement in subclasses" > + > def createColumn(self, soClass, col): > assert 0, "Implement in subclasses" raise NotImplementedError instead. > - if self.debug: > - self.printDebug(conn, q, 'QueryIns') > + #if self.debug: > + self.printDebug(conn, q, 'QueryIns') Oops? > Index: sqlobject/tests/dbtest.py > =================================================================== > --- sqlobject/tests/dbtest.py (revis??o 1061) > +++ sqlobject/tests/dbtest.py (c??pia de trabalho) > @@ -61,6 +61,7 @@ > if not isinstance(soClasses, (list, tuple)): > soClasses = [soClasses] > connection = getConnection() > + print connection Please do not print debugging output without "if debug:" or such. > + def postgresCreateReferenceConstraint(self): > + sTName = self.soClass.sqlmeta.table > other = findClass(self.foreignKey, self.soClass.sqlmeta.registry) > tName = other.sqlmeta.table > idName = other.sqlmeta.idName > @@ -719,16 +723,16 @@ > action = 'ON DELETE RESTRICT' > else: > action = '' > - constraint = ('CONSTRAINT %(colName)s_exists ' > + constraint = ('ALTER TABLE %(sTName)s ADD CONSTRAINT %(colName)s_exists ' > 'FOREIGN KEY (%(colName)s) ' > 'REFERENCES %(tName)s (%(idName)s) ' > '%(action)s' % > {'tName': tName, > 'colName': self.dbName, > 'idName': idName, > - 'action': action}) > - sql = ', '.join([sql, constraint]) > - return sql > + 'action': action, > + 'sTName': sTName}) > + return constraint Any idea what is the lowest version of Postgres that implements this? > def test_cyclic_reference(): > conn = getConnection() > TestCyclicReferenceA.setConnection(conn) > TestCyclicReferenceB.setConnection(conn) > TestCyclicReferenceA.dropTable(ifExists=True, cascade=True) > assert not conn.tableExists(TestCyclicReferenceA.sqlmeta.table) > TestCyclicReferenceB.dropTable(ifExists=True, cascade=True) > assert not conn.tableExists(TestCyclicReferenceB.sqlmeta.table) > > constraints = TestCyclicReferenceA.createTable(ifNotExists=True) > print constraints print! Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Ian B. <ia...@co...> - 2005-10-04 15:23:30
|
Oleg Broytmann wrote: > On Tue, Oct 04, 2005 at 09:48:16AM -0300, Jo?o Paulo Fernandes Farias wrote: > >>Unfortunately, I could not achieve my objective without changing the api for >>createTable and createTableSQL methods. > > > Hence it cannot be backported to 0.7.1. It actually seems like some new abstraction is called for. It seems like a complicated contract to call createTable, collect the results, and then create the constraints. Well... one option is the event system, which would allow created tables to listen for the other tables to be created; kind of like the class registry, except for CREATEs. >>- constraint = ('CONSTRAINT %(colName)s_exists ' >>+ constraint = ('ALTER TABLE %(sTName)s ADD CONSTRAINT %(colName)s_exists ' >> 'FOREIGN KEY (%(colName)s) ' >> 'REFERENCES %(tName)s (%(idName)s) ' >> '%(action)s' % >> {'tName': tName, >> 'colName': self.dbName, >> 'idName': idName, >>- 'action': action}) >>- sql = ', '.join([sql, constraint]) >>- return sql >>+ 'action': action, >>+ 'sTName': sTName}) >>+ return constraint > > > Any idea what is the lowest version of Postgres that implements this? I'm guessing at least 7.0 -- it took Postgres a while to support dropping constraints and other objects, but alters that add constraints have been part of the dump format. > >>def test_cyclic_reference(): >> conn = getConnection() >> TestCyclicReferenceA.setConnection(conn) >> TestCyclicReferenceB.setConnection(conn) >> TestCyclicReferenceA.dropTable(ifExists=True, cascade=True) >> assert not conn.tableExists(TestCyclicReferenceA.sqlmeta.table) >> TestCyclicReferenceB.dropTable(ifExists=True, cascade=True) >> assert not conn.tableExists(TestCyclicReferenceB.sqlmeta.table) >> >> constraints = TestCyclicReferenceA.createTable(ifNotExists=True) >> print constraints > > > print! Prints in test cases are okay. -- Ian Bicking / ia...@co... / http://blog.ianbicking.org |
From: Oleg B. <ph...@ph...> - 2005-10-04 15:46:41
|
On Tue, Oct 04, 2005 at 10:22:39AM -0500, Ian Bicking wrote: > > Any idea what is the lowest version of Postgres that implements this? > > I'm guessing at least 7.0 Good enough for me. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: <jpa...@gm...> - 2005-10-05 11:58:07
|
Hi guys! Well, this was only my first attemp to handle cases with cyclic reference. Do you think there is a better way to do that? I really dunno.... Maybe the event system can help here. But, I think that in any way, we can only achieve this by issuing the "ALTER TABLE ADD CONSTRAINT" after both (o= r more?) tables on the relation are created. PS: Sorry for the debugging print's.... -- JP On 10/4/05, Oleg Broytmann <ph...@ph...> wrote: > > On Tue, Oct 04, 2005 at 10:22:39AM -0500, Ian Bicking wrote: > > > Any idea what is the lowest version of Postgres that implements this? > > > > I'm guessing at least 7.0 > > Good enough for me. > > Oleg. > -- > Oleg Broytmann http://phd.pp.ru/ ph...@ph... > Programmers don't die, they just GOSUB without RETURN. > > > ------------------------------------------------------- > This SF.Net email is sponsored by: > Power Architecture Resource Center: Free content, downloads, discussions, > and more. http://solutions.newsforge.com/ibmarch.tmpl > _______________________________________________ > sqlobject-discuss mailing list > sql...@li... > https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss > |
From: Oleg B. <ph...@ph...> - 2005-10-05 11:20:03
|
On Wed, Oct 05, 2005 at 07:55:29AM -0300, Jo?o Paulo Fernandes Farias wrote: > Do you think there is a better way to do that? I really dunno.... I have no idea. Clean up your patch and resend - I think it's worth including. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: <jpa...@gm...> - 2005-10-05 11:58:32
Attachments:
cyclic1.diff
|
I've removed the debugging print's... Patch attached. -- JP On 10/5/05, Oleg Broytmann <ph...@ph...> wrote: > > On Wed, Oct 05, 2005 at 07:55:29AM -0300, Jo?o Paulo Fernandes Farias > wrote: > > Do you think there is a better way to do that? I really dunno.... > > I have no idea. Clean up your patch and resend - I think it's worth > including. > > Oleg. > -- > Oleg Broytmann http://phd.pp.ru/ ph...@ph... > Programmers don't die, they just GOSUB without RETURN. > |
From: Oleg B. <ph...@ph...> - 2005-10-05 12:17:39
|
On Wed, Oct 05, 2005 at 08:57:57AM -0300, Jo?o Paulo Fernandes Farias wrote: > I've removed the debugging print's... > Patch attached. It aplied almost cleanly and passed the test suite. Can you also add a test or two? Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: <jpa...@gm...> - 2005-10-05 12:33:13
Attachments:
test_cyclic_reference.py
|
I've supplied the test on my first post in this thread. I'll attach it again. -- JP On 10/5/05, Oleg Broytmann <ph...@ph...> wrote: > > On Wed, Oct 05, 2005 at 08:57:57AM -0300, Jo?o Paulo Fernandes Farias > wrote: > > I've removed the debugging print's... > > Patch attached. > > It aplied almost cleanly and passed the test suite. Can you also add a > test or two? > > Oleg. > -- > Oleg Broytmann http://phd.pp.ru/ ph...@ph... > Programmers don't die, they just GOSUB without RETURN. > |
From: Oleg B. <ph...@ph...> - 2005-10-05 12:55:18
|
On Wed, Oct 05, 2005 at 09:32:53AM -0300, Jo?o Paulo Fernandes Farias wrote: > I've supplied the test on my first post in this thread. Applied, tested and committed to the trunk at the revision 1077. Thank you very much! Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: <jpa...@gm...> - 2005-10-05 15:48:57
|
It would be nice to comment somewhere on the docs that klass.createTable() will return a list of constraints if it is applicable. createTable() no more create the constraints by itself. If the user wants the constraints on the database, it must execute a conn.query(constraint) for each constraint returned. -- JP On 10/5/05, Oleg Broytmann <ph...@ph...> wrote: > > On Wed, Oct 05, 2005 at 09:32:53AM -0300, Jo?o Paulo Fernandes Farias > wrote: > > I've supplied the test on my first post in this thread. > > Applied, tested and committed to the trunk at the revision 1077. Thank > you very much! > > Oleg. > -- > Oleg Broytmann http://phd.pp.ru/ ph...@ph... > Programmers don't die, they just GOSUB without RETURN. > |
From: Oleg B. <ph...@ph...> - 2005-10-05 13:29:46
|
On Wed, Oct 05, 2005 at 10:01:35AM -0300, Jo?o Paulo Fernandes Farias wrote: > It would be nice to comment somewhere on the docs that klass.createTable() > will return a list of constraints if it is applicable. > > createTable() no more create the constraints by itself. If the user wants > the constraints on the database, it must execute a conn.query(constraint) > for each constraint returned. createTable() is barely documented now. You can add whatever you want, and send a patch. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |