Thread: [SQLObject] Preparing for 0.6.1
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: Ian B. <ia...@co...> - 2004-12-29 17:06:58
|
Is there anything people know of that should be resolved before 0.6.1? As far as I can remember, it's just been a bunch of bug fixes since 0.6 (most from Oleg, thanks!) Also, I've been trying to add documentation as people note things are missing. So, if there's any other omissions people notice, or ideas for restructuring or whatever, I'd be interested in comments. -- Ian Bicking / ia...@co... / http://blog.ianbicking.org |
From: Oleg B. <ph...@ma...> - 2004-12-29 17:14:49
|
On Wed, Dec 29, 2004 at 11:06:48AM -0600, Ian Bicking wrote: > Also, I've been trying to add documentation as people note things are > missing. I cannot build SQLObject.txt using rst2html.py - SQLObject.txt references external code snippets that are not exist. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Ian B. <ia...@co...> - 2004-12-29 17:19:54
|
Oleg Broytmann wrote: > On Wed, Dec 29, 2004 at 11:06:48AM -0600, Ian Bicking wrote: > >>Also, I've been trying to add documentation as people note things are >>missing. > > > I cannot build SQLObject.txt using rst2html.py - SQLObject.txt > references external code snippets that are not exist. Woops, fixed in 505. -- Ian Bicking / ia...@co... / http://blog.ianbicking.org |
From: Oleg B. <ph...@ph...> - 2004-12-30 08:28:52
|
On Wed, Dec 29, 2004 at 11:19:45AM -0600, Ian Bicking wrote: > Oleg Broytmann wrote: > > I cannot build SQLObject.txt using rst2html.py - SQLObject.txt > >references external code snippets that are not exist. > > Woops, fixed in 505. $ ./build Traceback (most recent call last): File "./examplestripper.py", line 96, in ? snipAll(arg) File "./examplestripper.py", line 87, in snipAll snipAll(fn) File "./examplestripper.py", line 89, in snipAll snipFile(dir) File "./examplestripper.py", line 67, in snipFile f = open(fn + ".py.html") IOError: [Errno 2] No such file or directory: './snippets/slicing-batch.py.html' /home/phd/work/SQLObject/SQLObject/docs/FAQ.txt:26: (SEVERE/4) Problems with "raw" directive path: [Errno 2] No such file or directory: u'../examples/snippets/leftjoin-simple.html'. .. raw:: html :file: ../examples/snippets/leftjoin-simple.html Exiting due to level-4 (SEVERE) system message. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Oleg B. <ph...@ph...> - 2004-12-30 09:15:40
|
Also it is good time to overhaul Plan06.txt. Some things were implemented already, some plans were changed. Especiall I'm interested to hear your plans about inheritance. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Ksenia M. <kse...@gm...> - 2004-12-29 23:59:49
|
> Is there anything people know of that should be resolved before 0.6.1? I am not sure if this is a bug or a feature or my misunderstanding, but RelatedJoin does not create constrains on the intermediate table (I am using PostgreSQL 7.4). And a very related problem: the many-to-many relations between objects are not deleted after destroying the objects. The following test does not remove row from intermediate table: class Person(SQLObject): name = StringCol() addresses = RelatedJoin('Address') class Address(SQLObject): street = StringCol() persons = RelatedJoin('Person') Person.dropTable(ifExists=True) Person.createTable() Address.dropTable(ifExists=True) Address.createTable() p = Person(name='John') a = Address(street='Some street') p.addAddress(a) p.destroySelf() a.destroySelf() ~ -- Ksenia |
From: Brian B. <ex...@gm...> - 2004-12-30 01:02:51
|
Ian Bicking wrote: > Is there anything people know of that should be resolved before 0.6.1? > As far as I can remember, it's just been a bunch of bug fixes since 0.6 > (most from Oleg, thanks!) Starting with version 2.0 (a while ago), SQLite has supported transactions, so maybe the documentation can be updated, and code if necessary? Doing some timings with insert/update and commit with SQLObject seems to suggest that even though SQLite supports transactions, SQLObject doesn't really take advantage of them. Is this the case? -- Brian Beck Adventurer of the First Order |
From: Oleg B. <ph...@ma...> - 2004-12-30 08:24:20
|
On Wed, Dec 29, 2004 at 08:02:15PM -0500, Brian Beck wrote: > Starting with version 2.0 (a while ago), SQLite has supported > transactions, so maybe the documentation can be updated, and code if > necessary? Doing some timings with insert/update and commit with > SQLObject seems to suggest that even though SQLite supports > transactions, SQLObject doesn't really take advantage of them. Is this > the case? sqlobject/sqlite/sqliteconnection.py supportTransactions = True Looks ok. What is wrong in your case? Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Brian B. <ex...@gm...> - 2004-12-31 06:02:49
|
Oleg Broytmann wrote: > Looks ok. What is wrong in your case? I'm not sure if I have the specific code anymore, but I will try to reproduce it if necessary. The issue is described below. - Do only methods that are passed the transaction provided by conn.transaction() take advantage of it? If so, how do you insert new rows within a transaction? I can only see one way to create a new row, i.e.: Person(name='Brian'), but no way to pass this a transaction 'instance' (I tried a few different ways). Given the above question, I can't remember exactly on what code I settled in which I thought row creations were being done within a transaction. But I did a time.clock() in 3 places: before create/insert (t1), after create/insert (t2), and after commit (t3). The difference between t2 and t1 was very large, and the difference between t3 and t2 was close to 0. So, insertions were being auto-committed and thus not within the transaction. A better explanation of how to do this would be appreciated. -- Brian Beck Adventurer of the First Order |
From: Luke O. <lu...@me...> - 2004-12-31 08:39:28
|
Quoting Brian Beck <ex...@gm...>: > - Do only methods that are passed the transaction provided by > conn.transaction() take advantage of it? If so, how do you insert new > rows within a transaction? I can only see one way to create a new row, > i.e.: Person(name='Brian'), but no way to pass this a transaction > 'instance' (I tried a few different ways). trans = conn.transaction() ... Person(name='Brian', connection=trans) (To your question, yes, and the constructor/create method takes a connection argument like all the others.) On the topic of 0.6.1 and transactions, how are people dealing with pre-existing objects that need to be updated in a transaction? In my base class I add a method to return a copy of the object in a new transaction: def inConnection(connection): return self.__class__.get(self.id, connection=connection) brian = Person.get(1) ... # use brian for display or whatever trans = conn.transaction() ... # now need to update brian in trans brianForUpdate = brian.inConnection(trans) brianForUpdate.set(...) Although I suppose nearly the same effect could be had by: brian._connection = trans Although, will brian be moved out of the old connection's cache? Be added to the new connection's (transaction's) cache? If I have other references of the cached object, they'll suddenly be in the transaction, right? Seems to me that's why I orginally wrote inConnection to re-instantiate. So how are other people dealing with this situation? I know way way back we talked about a copyToConnection method which did a little more (would create the object in the new connection if it didn't exist in that database say). - Luke P.S. Speaking of local additions to all my SO classes, I have a method getByID that wraps get() in a try-except and returns None if it wasn't found, for code situations where it's less clear to use exceptions: person = Person.get(req.field('id',None)) if not person: person = Person(...) Useful? |
From: Oleg B. <ph...@ma...> - 2004-12-31 12:59:25
|
On Fri, Dec 31, 2004 at 01:02:25AM -0500, Brian Beck wrote: > - Do only methods that are passed the transaction provided by > conn.transaction() take advantage of it? If so, how do you insert new > rows within a transaction? I can only see one way to create a new row, > i.e.: Person(name='Brian'), but no way to pass this a transaction > 'instance' (I tried a few different ways). The simplest method is to create a connection, wrap it into a transactiona and after that decalre your tables: conn = connectionForURI("...") if connection.supportTransactions: conn = conn.transaction() class Person(SQLObject): _connection = conn Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Carlos R. <car...@gm...> - 2004-12-31 13:05:49
|
On Fri, 31 Dec 2004 15:59:15 +0300, Oleg Broytmann <ph...@ma...> wrote: > On Fri, Dec 31, 2004 at 01:02:25AM -0500, Brian Beck wrote: > > - Do only methods that are passed the transaction provided by > > conn.transaction() take advantage of it? If so, how do you insert new > > rows within a transaction? I can only see one way to create a new row, > > i.e.: Person(name='Brian'), but no way to pass this a transaction > > 'instance' (I tried a few different ways). > > The simplest method is to create a connection, wrap it into a > transactiona and after that decalre your tables: > > conn = connectionForURI("...") > if connection.supportTransactions: > conn = conn.transaction() > > class Person(SQLObject): > _connection = conn Genuinely curious. What are the actual semantics of this? Do it opens a transaction for the entire lifetime of the connection, or does it use a transaction for each operation? The first is not useful, and the later seems like overkill (not to mention that the granularity of the transaction, in both cases, leaves a lot to be desired). -- Carlos Ribeiro Consultoria em Projetos blog: http://rascunhosrotos.blogspot.com blog: http://pythonnotes.blogspot.com mail: car...@gm... mail: car...@ya... |
From: Oleg B. <ph...@ph...> - 2004-12-31 13:11:51
|
On Fri, Dec 31, 2004 at 11:05:41AM -0200, Carlos Ribeiro wrote: > > conn = connectionForURI("...") > > if connection.supportTransactions: > > conn = conn.transaction() > > > > class Person(SQLObject): > > _connection = conn > > Genuinely curious. What are the actual semantics of this? Do it opens > a transaction for the entire lifetime of the connection, or does it > use a transaction for each operation? The first is not useful, and the > later seems like overkill (not to mention that the granularity of the > transaction, in both cases, leaves a lot to be desired). Neither. You can call conn.begin(), conn.commit() and conn.rollback() at your will. After calling conn.rollback() you have to call conn.begin(). That's simple. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Luke O. <lu...@me...> - 2004-12-31 17:58:03
|
Quoting Oleg Broytmann <ph...@ph...>: > On Fri, Dec 31, 2004 at 11:05:41AM -0200, Carlos Ribeiro wrote: >> > conn = connectionForURI("...") >> > if connection.supportTransactions: >> > conn = conn.transaction() >> > >> > class Person(SQLObject): >> > _connection = conn >> > Neither. You can call conn.begin(), conn.commit() and conn.rollback() > at your will. After calling conn.rollback() you have to call > conn.begin(). That's simple. Am I correct in thinking this is unusable in a multi-threaded environment, like Webware? The Person class shares one underlying connection to the database (pool is bypassed by Transaction), so if I have two interleaved requests to an UpdateUser process (whether for different user records or not) they will both try to begin(), and when one commits the other's changes up to that point go along, or a rollback in one ends the transaction for the other? Or am I missing something? - Luke |
From: Carlos R. <car...@gm...> - 2004-12-31 18:25:53
|
On Fri, 31 Dec 2004 11:57:55 -0600, Luke Opperman <lu...@me...> wrote: > Quoting Oleg Broytmann <ph...@ph...>: > > > On Fri, Dec 31, 2004 at 11:05:41AM -0200, Carlos Ribeiro wrote: > >> > conn = connectionForURI("...") > >> > if connection.supportTransactions: > >> > conn = conn.transaction() > >> > > >> > class Person(SQLObject): > >> > _connection = conn > >> > > Neither. You can call conn.begin(), conn.commit() and conn.rollback() > > at your will. After calling conn.rollback() you have to call > > conn.begin(). That's simple. > > Am I correct in thinking this is unusable in a multi-threaded > environment, like > Webware? The Person class shares one underlying connection to the database > (pool is bypassed by Transaction), so if I have two interleaved requests to an > UpdateUser process (whether for different user records or not) they will both > try to begin(), and when one commits the other's changes up to that point go > along, or a rollback in one ends the transaction for the other? > > Or am I missing something? I may be wrong, but some kinds of connection objects are thread-sefe. There's some info on the threadsafety value that is exposed by the DBAPI 2.0... I don't have enough experience to tell how does it behave in practice. -- Carlos Ribeiro Consultoria em Projetos blog: http://rascunhosrotos.blogspot.com blog: http://pythonnotes.blogspot.com mail: car...@gm... mail: car...@ya... |
From: Oleg B. <ph...@ma...> - 2004-12-31 18:33:58
|
On Fri, Dec 31, 2004 at 11:57:55AM -0600, Luke Opperman wrote: > >>> conn = connectionForURI("...") > >>> if connection.supportTransactions: > >>> conn = conn.transaction() > >>> > >>> class Person(SQLObject): > >>> _connection = conn > >> > > Neither. You can call conn.begin(), conn.commit() and conn.rollback() > >at your will. After calling conn.rollback() you have to call > >conn.begin(). That's simple. > > Am I correct in thinking this is unusable in a multi-threaded > environment I don't know. I have never used threads and I hope I'll never use it. The above code works great in a forking server (Quixote+SCGI). Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Ian B. <ia...@co...> - 2004-12-31 19:09:34
|
Luke Opperman wrote: > Quoting Oleg Broytmann <ph...@ph...>: > >> On Fri, Dec 31, 2004 at 11:05:41AM -0200, Carlos Ribeiro wrote: >> >>> > conn = connectionForURI("...") >>> > if connection.supportTransactions: >>> > conn = conn.transaction() >>> > >>> > class Person(SQLObject): >>> > _connection = conn >>> >> Neither. You can call conn.begin(), conn.commit() and conn.rollback() >> at your will. After calling conn.rollback() you have to call >> conn.begin(). That's simple. > > > Am I correct in thinking this is unusable in a multi-threaded > environment, like > Webware? The Person class shares one underlying connection to the database > (pool is bypassed by Transaction), so if I have two interleaved requests > to an > UpdateUser process (whether for different user records or not) they will > both > try to begin(), and when one commits the other's changes up to that > point go > along, or a rollback in one ends the transaction for the other? It's compatible with threads, you just have to pass the connection in anytime it might be ambiguous what transaction you are working in (i.e., whenever you are dealing with class methods). Though I'm curious what people do in Zope 3, if there's anything special in sqlo... there transactions are often per-thread (which is actually a lot more convenient, since you don't have to pass the connection around, and usually what you really want anyway). -- Ian Bicking / ia...@co... / http://blog.ianbicking.org |
From: Sidnei da S. <si...@aw...> - 2004-12-31 19:19:57
|
| It's compatible with threads, you just have to pass the connection in | anytime it might be ambiguous what transaction you are working in (i.e., | whenever you are dealing with class methods). Though I'm curious what | people do in Zope 3, if there's anything special in sqlo... there | transactions are often per-thread (which is actually a lot more | convenient, since you don't have to pass the connection around, and | usually what you really want anyway). We keep a connection always open for each thread and used a descriptor for the _connection attribute of SQLObject to fetch this open connection using the thread id. -- Sidnei da Silva <si...@aw...> http://awkly.org - dreamcatching :: making your dreams come true http://www.enfoldsystems.com http://plone.org/about/team#dreamcatcher Know Thy User. |
From: Ian B. <ia...@co...> - 2004-12-30 17:06:20
|
Brian Beck wrote: > Starting with version 2.0 (a while ago), SQLite has supported > transactions, so maybe the documentation can be updated, and code if > necessary? Doing some timings with insert/update and commit with > SQLObject seems to suggest that even though SQLite supports > transactions, SQLObject doesn't really take advantage of them. Is this > the case? The documentation was inaccurate about SQLite and transactions; I've removed that from the documentation. -- Ian Bicking / ia...@co... / http://blog.ianbicking.org |
From: Stuart B. <st...@st...> - 2005-01-06 08:40:50
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Ian Bicking wrote: | Is there anything people know of that should be resolved before 0.6.1? | As far as I can remember, it's just been a bunch of bug fixes since 0.6 | (most from Oleg, thanks!) I would like to see the death of __del__ methods, or at the very least swallowing any exceptions raised inside them. The spurious warnings are causing our test suite grief (but it won't be the end of the world if it isn't in the next release). __del__ methods seem to have little use except to confuse the Python garbage collector and generate random bugs, so I personally consider code that relies on them broken ;) I'll work on a patch unless someone beats me to it. - -- Stuart Bishop <st...@st...> http://www.stuartbishop.net/ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (GNU/Linux) iD8DBQFB3PmGAfqZj7rGN0oRAgvQAJ4toPE3kESwokPQ2de7f81pAp+axQCbBGvu P+R03geRUqWSQ/u6Js/UF5g= =Xdcm -----END PGP SIGNATURE----- |