I have a small Django project with simple models. However, instead of creating my database via python manage.py syncdb I decided to create it manually and map the tables via Meta, as shown below
class Item(models.Model):
name = models.CharField(max_length=50)
class Meta:
managed = False
db_table = 'ITEM'
but this doesn't work. When I start the development server and run the main view, Django throws an error saying that the relation named ITEM doesn't exist in the database, when in fact it does exist.
I have done some research but couldn't find anyone with such a problem. Is there a way I can get it working?
The db_table name should be in lowercase:
db_table = 'item'
Postgres converts table names to lowercase letters unless the queries have quotes around them. See for example:
http://binodsblog.blogspot.com/2011/02/postgresql-is-case-sensitive.html
Normally that detail is abstracted away by the ORM, but if you don't use syncdb, you have to manage it.
Related
I have multiple models that I'd like to create tables for. So far I've been running sql code to create them and then i can make use of them. This seems tedious and I'm pretty sure django can do it for me. After all it creates tables with makemigrations and migrate. But this does not seem to work with my models.
EDIT: Here's what I mean
I have a model like the following
class Article(models.Model):
headline = models.CharField(max_length=200)
content = models.TextField()
...
class Meta:
managed = False
db_table = 'main_article'
So far I've been creating the main_article table manually by running this code in psycopg2:
CREATE TABLE IF NOT EXISTS public.main_article (
id SERIAL PRIMARY KEY,
headline varchar 200 NOT NULL,
content text NOT NULL,
...
);
This is a real pain and I'm sure it will lead to errors and bugs. How can i get this table to be created automatically? I tried doing
python manage.py makemigrations main
python manage.py migrate main
With no success.
Btw 'main' is the name of my app.
Hope it's more clear now.
Thanks in advance!
For anyone still wondering, my problem was that I had set managed to false. Simply changing this did the trick.
I am creating a Django web application and I am using Postgres for my database.
Under my project, I have a web application named 'home', and I created a table named 'myTable' in Postgres.
Whenever I try to save something in the table, Django automatically looks for the table called 'home_myTable' instead of 'myTable'. For example, if I do
python manage.py migrate
I get the following error:
django.db.utils.ProgrammingError: relation "home_myTable" does not exist
I have been working around this by manually giving Postgres commands using Psycopg2, but this is really annoying.
Is there a way to stop Django from automatically start looking for 'home_myTable' and instead make it search the table that I want?
You can set the db_table Meta option for you model.
class MyTable(models.Model):
...
class Meta:
db_table = 'mytable'
Unless you are dealing with a legacy database, I recommend that you define your models, create migrations, then let Django create the tables, instead of creating the tables manually as you are doing.
I am getting this error for a django model:
ProgrammingError at /admin/notifications/eventtoken/
column notifications_eventtoken.user_id does not exist
LINE 1: ...ications_eventtoken" INNER JOIN "users_user" ON ( "notificat...
^
HINT: Perhaps you meant to reference the column "notifications_eventtoken.used_at".
I added a foreign key for user like this:
class EventToken(models.Model):
token = models.CharField(max_length=255, db_index=True)
user = models.ForeignKey(User, null=False, blank=False)
used_at = models.DateTimeField(null=True, blank=True)
event = models.ForeignKey(Event)
it works when I remove the user field, but breaks otherwise and I can't tell much from the error message.
It works when I remove the user field.
This is because your database is missing a column that you have programmed in your EventToken class which I'm guessing is inside of notifications/models.py. This is why it is called a ProgrammingError.
There are several ways to solve this:
1. Delete your entire database and sync it again! Not recommended for anything running on production, but for test projects really doesn't hurt much.
2. Use a tool like south or the django migrate app (depending on which django version you're using) to automate adding a table to your database using the manage.py script. Edit: this solution is the most viable as it's quick and adheres to DRY principles when working across multiple development environments.
3a. Manually go into your database using a command line tool and add the missing column. If I haven't made it clear... you're saying "I want to save the user_id" foreign key in this table" while your table is saying back "There is nowhere to save this ID." ...)
3b. Use a database GUI (like PGadmin for postgresql) and add the user_id column to your notifications_eventtoken database table.
4. Delete the user field in the EventToken class! Don't do this, but understand it works because it clears the logical discrepancy.
I found an interesting behavior in djangos syncdb mechanism, as I tried to sync my database for a new deployment last time.
I got two apps alphabet and core where core stores most of my models.
Now I created a new abstract model in alphabet with a code like:
class Compare(models.Model):
percentage = FloatField(default=0)
speakers = IntegerField(default=Speaker.objects.count())
class Meta:
abstract = True
and the referring model in the core app:
class Speaker(models.Model):
language = CharField(max_length=300)
When I try to sync the database with the syncdb command it fails with ProgrammingError because the table core.speaker does not exist.
Why is syncdb even checking abstract models? How can I solve this circular reference in my project?
(I am using Django 1.6 by the way)
Calling count() in the field definition is incorrect. Django tries to evaluate the query when the model is loaded. In your case, this is before the table has even been created. Even if the table had been created, the query would only be evaluated once each time the module loads, and would not update as instances were created and deleted.
You can pass a callable to a model field as the default, so you could try
speakers = IntegerField(default=Speaker.objects.count)
Then the query will be evaluated when the model instance is created.
I added a many-to-many field to an existing model and was expecting syncdb to create a new table, but there's nothing there. This is what the model looks like:
class Author(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
def __unicode__(self):
return "{0} {1}".format(self.first_name, self.last_name)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
def __unicode__(self):
return self.title
Running sql myapp prints the correct statements with the new table, but this is not reflected when I run syncdb. validate also returns no errors. Does anyone know what could be the matter here? Or a better diagnostic?
The syncdb command does not create many to many tables for existing models by design. This decision is explained on ticket 2229.
That leaves you with a few options.
If you don't have any data in your Book model, drop the table and rerun syncdb. Django will recreate the book table and the many to many table.
Use the dbshell command, and create the many to many joining table using the output of sql myapp.
If you're doing multiple schema migrations with Django, make friends with South.
I found this explanation at the django docs useful: SchemaEvolution.
The de facto standard for database migration is Django South.
Its not perfect, but, it works pretty well. You should always check(and edit if necessary) your migration file before running it, to make sure that it actually does what it supposed to do.
You can check out their tutorial here.
Also, if you run:
python manage.py inspectdb > somefile.txt
You can get quickly check out if your database structure is matching your django models.