samedi 3 janvier 2015

Python mixing multiple ORMs

TL;DR I'm write to an sqlite DB with peewee and want to read it with both django and peewee- 'no such table' error is raised.


Longer story: I've got a piece of scientific code that outputs results to a sqlite database (because it is easy to query it later). The writing is done peewee- I wrote model classes, etc. I also wrote some code to look at the results, and also used peewee, everything was fine. This was ran in an IPython notebook.


At some point I decided it is a good idea to build a django app to look at the results. To let django read the same DB, I duplicated the model classes in django, and added managed=False like so:



import peewee as pw
class Results(pw.Model):
id = pw.ForeignKeyField(Experiment)
classifier = pw.CharField(null=False)
accuracy_mean = pw.DoubleField(null=False)
class Meta:
database = db
primary_key = pw.CompositeKey('id', 'classifier')


the corresponding class in django is



from django.db import models
class Results(models.Model):
id = models.ForeignKey(Experiment, primary_key=True)
classifier = models.CharField(max_length=255)
accuracy_mean = models.FloatField()

class Meta:
managed = False
db_table = 'results'


Using django's ORM to query the DB was also fine. However, at some point I noticed I had lots of duplicated code that effectively does the same thing, but one version uses django's ORM, and one uses peewee. I decided to keep the peewee version because it is an overkill to run django just for the ORM (e.g. in a notebook). I would still like to use the django-specific code I've got, but I want peewee to handle some of the queries in a django view. Here is the shared function:



def some_view():
rows = Results.select().where(Results.id == n)
rows = sorted(rows, key=attrgetter('cv_fold'))
return [x.accuracy for x in rows]


At this point peewee complains that "OperationalError no such table: results". This only happens when the code is run by visiting the url that maps to some_view. If I run same_function in an IPython console, things work just fine. That leads me to believe django is interfering with peewee somehow.


My question(s) are:



  • in the short term, how do I get around the no-such-table error?

  • in the long term, how could I have designed this better, so that code is seamlessly shared between the "front end" and the "back end"? Using multiple libraries to do the same thing is a not ideal, and neither is only using django. I suppose I could have done the web app in Pylons+SQLAlchemy, and SQLAlchemy in the backend. At this stage I would have to re-write a lot of code, so I'm a bit reluctant to go down that route.


Aucun commentaire:

Enregistrer un commentaire