I have a Django app using MySQL with a medium-sized database and now I'm looking at migrating it to PostgreSQL. I've created a table and loaded the data, so now I can perform basic SQL queries.
From the Django side this has been more difficult. I get the following error message:
"ProgrammingError: relation "myapptable" does not exist
LINE 1: ..."myapptable"."name", "myapptable"."birthday" FROM "myapptabl...
I've looked at the SQL and it seems that with PostgreSQL, the ORM adds extra quotes around the table name. This isn't a problem with Django-created tables, only with "unmigrated" tables. That's the term used in the migration section of the Django 1.7 docs. I've tested this with both 1.7 and 1.6.
Here’s some simplified source code:
models.py
from django.db.models import Model, CharField, DateField, IntegerField
class MyTest(Model):
id = IntegerField(primary_key = True)
name = CharField(max_length = 20)
birthday = DateField()
class Meta:
app_label = 'mytest'
db_table = 'myapptable'
managed = False
def __unicode__(self):
return self.name
PostgreSQL table
CREATE TABLE myapptable (
id serial PRIMARY KEY NOT NULL,
name varchar NOT NULL,
birthday date NOT NULL
);
MySQL table
CREATE TABLE myapptable (
id integer PRIMARY KEY AUTO_INCREMENT NOT NULL,
name varchar(20) NOT NULL,
birthday date NOT NULL
);
Django query
from datetime import date
from apps.filter.mytest.models import MyTest
qs = MyTest.objects.filter(
birthday__gte = date(2007, 01, 01)
).filter(
birthday__lte = date(2007, 12, 31)
)
for row in qs:
print(
'{}, {}'.format(
row.name,
row.birthday
)
)
PostgreSQL query
test version for the psql client (this works):
SELECT name, birthday
FROM myapptable
WHERE birthday
BETWEEN '2007-01-01 00:00:00'
AND '2007-12-31 00:00:00';
what the ORM generates (this generates the ProgrammingError message):
SELECT "myapptable"."id", "myapptable"."name", "myapptable"."birthday"
FROM "myapptable"
WHERE "myapptable"."birthday"
BETWEEN '2007-01-01 00:00:00'
AND '2007-12-31 00:00:00';
MySQL query
test version for the MySQL client (this works):
SELECT name, birthday
FROM myapptable
WHERE birthday
BETWEEN '2007-01-01 00:00:00'
AND '2007-12-31 00:00:00';
what the ORM generates (this also works):
SELECT `myapptable`.`id`, `myapptable`.`name`, `myapptable`.`birthday`
FROM `myapptable`
WHERE (
AND `myapptable`.`birthday`
BETWEEN '2007-01-01 00:00:00'
AND '2007-12-31 00:00:00');