Search code examples
pythonmysqldjangoshellinnodb

MySQL: Django .create followed by .get doesn't work without re-opening the shell


>>> Anything.objects.create(title='test')
<Anything: test>
>>> Anything.objects.get(title='test')
DoesNotExist: Anything matching query does not exist.
>>> exit()

... reopen shell ...

>>> Anything.objects.get(title='test')
<Anything: test>

Super stumped here. Running Python 2.7.3; Django 1.5.4; MySQL 5.5 (innodb), Ubuntu 12.04.

Furthermore, opening the python shell first, and running an insert statement against mysql results in a similar situation where the record exists in the database, but the shell cannot find it.

Dumping the mysql log shows what you would expect: An insert statement, followed by a select; It seems to somehow be going against an outdated version of the database -- a version that seems to have been established at the beginning of the shell instance!

Running sequential insert and select statements directly against the database yields a similar result; where you cannot access the new information since the shell was instantiated.

Still chasing this down:

>>> t = TagManager.objects.create(title='test')
>>> t
<TagManager: test>
>>> t.id
1L
>>> TagManager.objects.get(title='test')
<TagManager: test>
>>> t2 = TagManager.objects.create(title='test2')
>>> TagManager.objects.get(title='test2')
DoesNotExist: TagManager matching query does not exist.
>>> t2.id
2L
>>> TagManager.objects.get(title='test2')
DoesNotExist: TagManager matching query does not exist.
>>> TagManager.objects.get(title='test')
<TagManager: test>

Exit shell...

>>> TagManager.objects.get(title='test2')
<TagManager: test2>
>>> TagManager.objects.create(title='test3')
<TagManager: test3>
>>> t.id
3L
>>> TagManager.objects.get(title='test3')
DoesNotExist: TagManager matching query does not exist.
>>> t = TagManager.objects.create(title='test4')
>>> t
<TagManager: test4>
>>> t.id
4L
>>> TagManager.objects.get(title='test4')
DoesNotExist: TagManager matching query does not exist.

Solution

  • Turns out this was due to the REPEATABLE READ transaction isolation level that is the default behavior in MySQL

    http://django.readthedocs.org/en/latest/topics/db/transactions.html#using-a-high-isolation-level

    Changing the transaction-isolation level in the mysql conf to be READ COMMITTED solves this.