Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #763 (closed defect: fixed)

Opened 8 years ago

Last modified 4 years ago

exceptions.AttributeError: "'pysqlite2.dbapi2.Connection' object has no attribute 'autocommit'"

Reported by: jorge.vargas@… Owned by: anonymous
Priority: high Milestone: 1.5
Component: SQLObject Version: 0.9a4
Severity: normal Keywords: pysqlite sqlite SQLObject
Cc:

Description

This is a recurrent error that has happen a to many people and it looks random, so lets try to find out whats the problem.

Using database URI <value in your conf file> Exception exceptions.AttributeError?: "'pysqlite2.dbapi2.Connection' object has no attribute 'autocommit'" in <bound method Transaction.del of <sqlobject.dbconnection.Transaction object at 0xHEX>> ignored

  • this is of course a sqlite issue
  • this seems to happen mostly on linux
  • this happens only with some Models

Change History

comment:1 Changed 8 years ago by ghaering

Somebody please forward this to the SQLObject people:

This happens because in SQLObject's sqlite/dbconnection.py in the method _setAutoCommit() the check "if using_sqlite2" fails even though this global variable should be set at this point. But for some reason, it isn't, so the code path that was intended for pysqlite 1.x is executed against a pysqlite 2.x Connection object and fails.

I believe it does happen when there is an error during model creation, and SQLObject tries to roll back. Minimal model to reproduce:

from sqlobject import *
from turbogears.database import PackageHub

hub = PackageHub("test")
__connection__ = hub

class Foo(SQLObject):
    bar = MultipleJoin("Bar")

comment:2 Changed 8 years ago by jorge.vargas@…

I got to the same conclusion but I didn't find the problem (I have never look at SQLOBject code so I had no idea where to look for it)

I should also note that this happens on a RelatedJoin? also. This is the model I try I start getting the error ones I added the RelatedJoin? to B

from sqlobject import * from turbogears.database import PackageHub?

hub = PackageHub?("wiki20") connection = hub

class Page(SQLObject):

pagename=StringCol?(alternateID=True, length=30) data=StringCol?()

class B(SQLObject):

number=IntCol?() a=RelatedJoin?('Page')

comment:3 Changed 8 years ago by jvanasco@…

Just a note-

The new Widgets tutorial:

http://trac.turbogears.org/turbogears/wiki/IntroductionToWidgets

will cause this error on mac osx 10.4.5 / mac python 2.4.1 / tg 0.9a4 , and sqlite from cheesehop

comment:4 Changed 8 years ago by ghaering

It seems that the real problem is buried deep inside TurboGears and results from a lot of magic that gets out of hands:

  • the exception is raised because a Transaction object gets garbage-collected
  • the transaction object is stored in a thread-local variable
  • at the time the Transaction is garbage-collected, other things it depends on have already been collected => ERROR

This could be fixed if the transaction object is reset at an appropriate point in time. For this to happen, I think the AutoConnect/PackageHub? must get an additional method to reset its connections/transactions.

This could be fired when a special function in the model module has been called.

comment:5 Changed 8 years ago by jorge.vargas

a work around to this is to disable transactions in sqlite.

sqlobject.dburi="notrans_sqlite:///file_name_and_path"

taken from  http://tinyurl.com/oy42j

comment:6 Changed 8 years ago by kevin

  • Milestone changed from 0.9a5 to 1.0b1

comment:7 Changed 8 years ago by maxb

Seems something similar happens with pysqlite 1.x too - different exception:

Exception exceptions.AttributeError?: "'NoneType?' object has no attribute 'releaseConnection'" in <bound method Transaction.del of <sqlobject.dbconnection.Transaction object at 0x409fc24c>> ignored

but looks similar and the notrans_ workaround works here too.

comment:8 Changed 8 years ago by jorge.vargas

  • Milestone changed from 1.0b1 to 1.0

comment:9 Changed 8 years ago by igorfoox

I've stumbled on this problem as well. I've tried the workaround suggested in the  mailing list thread but it doesn't seem to be working for me. However the workaround suggested in #279 (using soClasses to define the order in which tables are created) does work for me.

comment:10 Changed 8 years ago by dreweskooi

This ticket has been active for a while, any updates? I got the book Rapid Web applicatiosn with Turbogears and am more or less stuck since in chapter 5 I keep getting this error!

comment:11 Changed 8 years ago by alberto

  • Milestone changed from 1.0 to 1.1

comment:12 Changed 8 years ago by jorge.vargas

sadly this is one of those things noone knows why is it happening.

comment:13 Changed 7 years ago by passive

I'm pretty much brand new to TurboGears, and trying to follow this tutorial:  http://exogen.case.edu/turbogears.html

I'm getting this error on the first tg-admin sql create.

I previously worked through the beginning of the wiki tutorial, and I did not have this problem.

I've got Python 2.4.3, sqlite 3.3.5, and pysqlite 2.3.1, on Gentoo.

comment:14 Changed 7 years ago by alberto

  • Milestone changed from 1.1 to __unclassified__

Batch moved into unclassified from 1.1 to properly track progress on the later

comment:15 Changed 7 years ago by digulla

I've added

print using_sqlite2

at several places in sqlite/sqliteconnection.py. Here is the output:

True True ... None

If I replace the "if using_sqlite2:" in _setAutoCommit() with "if True:", then I get the NoneType? error from comment 06/12/06. This is caused from calling

DBAPI.releaseConnection(self, conn, explicit=explicit)

in _setAutoCommit() because DBAPI is None.

I have the feeling that this happens because a lot of objects are already garbare collected when releaseConnection() is called. This would also explain why it's a flacky error.

I could fix the problem with this change at the top of releaseConnection (thirdparty/sqlobject/sqlobject/sqlite/sqliteconnection.py:144):

if self._memory or DBAPI is None:

return

(I added a check to return if DBAPI is None).

My system: SuSE 10.2, Python 2.5, TG 1.0.2 from SVN, SQLObject 0.8.

comment:16 Changed 7 years ago by alberto

  • Milestone changed from __unclassified__ to 1.0.2

comment:17 Changed 7 years ago by digulla

Sorry, just saw a typo. The call trace is:

Transaction.__del__ (dbconnection.py:913)
Transaction.rollback (dbconnection.py:872)
Transaction._makeObsolete (dbconnection.py:896)
SQLiteConnection._setAutoCommit (sqliteconnection.py:~167) <-- Crash #1 here
SQLiteConnection.releaseConnection (sqliteconnection.py:~152) <-- Crash #2 here

makeObsolete() makes the two last calls (and not _setAutoCommit() as I wrote above). The line numbers in sqliteconnection.py are off a bit because I've sprinkled the code with debug print's :-)

comment:18 Changed 7 years ago by alberto

  • Milestone changed from 1.0.2 to 1.0.3

comment:19 Changed 7 years ago by 3david

If you add: joinColumn="parent_table_id_column" to the MultipleJoin? statement the exception disappears.

e.g.

class Foo(SQLObject):

bar = MultipleJoin?("Bar", joinColumn="foo_id")

comment:20 Changed 7 years ago by digulla

Maybe but that doesn't solve the root cause of the problem. It just hides it.

comment:21 Changed 7 years ago by faide

  • Milestone changed from 1.0.3 to 1.1

comment:22 Changed 6 years ago by faide

  • Milestone changed from 1.1 to 1.1.1

comment:23 Changed 6 years ago by kskuhlman

  • Status changed from new to closed
  • Resolution set to fixed
  • Milestone changed from 1.6 to 1.5

The change to use connection.expireAll() for #85 should clear up this issue, if it still exists.

comment:24 Changed 6 years ago by chrisz

  • Status changed from closed to reopened
  • Resolution fixed deleted

As reported  here, the problem still exists.

I think there are two problems here. 1) The del method of SQLObject transactions is not very robust, it should silently ignore errors if things that it wants to clean up do not exist any more. This could be improved in SQLObject. 2) SQLObject unnecessarily creates transactions when defining a complex model with inheritance or two-way references. The PackageHub does not, as advertised, instantiate the AutoConnectHub when an attempt is made to use the database, but sometimes already earlier, because during model definition, if the model uses inheritance or two-way references, the connection is accessed as an attribute internally by SQLObject, and at this time TG unnecessarily instantiates the AutoConnectHub already, which automatically creates a connection and also a transaction already.

Ticket #2160 is also caused by 2). The second patch suggested there (it can be applied to all 1.x versions) should solve the issue.

comment:25 Changed 6 years ago by chrisz

  • Status changed from reopened to closed
  • Resolution set to fixed

Patch was applied in r6206.

Note: See TracTickets for help on using tickets.