Setting database with django - python

I created a db with such tracks.models:
class Song(models.Model):
title = models.CharField(max_length=30)
album = models.ForeignKey(Album)
def __unicode__(self):
return self.title
and used
python manage.py sqall tracks
python manage.py syncdb
but then I changed models to
class Song(models.Model):
songid = models.CharField(max_length=30)
title = models.CharField(max_length=30)
album = models.ForeignKey(Album)
def __unicode__(self):
return self.title
and did
python manage.py sqall tracks
python manage.py syncdb
again. Output of sqall:
BEGIN;
CREATE TABLE "tracks_song" (
"id" integer NOT NULL PRIMARY KEY,
"songid" varchar(30) NOT NULL,
"title" varchar(30) NOT NULL,
"album_id" integer NOT NULL REFERENCES "tracks_album" ("id")
)
;
CREATE INDEX "tracks_song_6781e42a" ON "tracks_song" ("album_id");
COMMIT;
syncdb:
Creating tables ...
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
But whenever I tried to access tracks.models.Song.all() it said:
OperationalError: no such column: tracks_song.songid
So I decided to
python manage.py flush
python manage.py sqall tracks
python manage.py syncdb
(same output)
But problem hasn't gone and there's still no such column: tracks_song.songid.
What's the problem behind it?

python manage.py sqlall app-name will only print SQL sentences, not create or change database structures, that is to say, it's used to check or tell you what django actually do in databases. Howerver, django version<1.7 doesn't track changes of class in models.py(newly increased or delete existed class could be detected and syncdb), but you can use south, or django 1.7 to do such thing.
python manage.py flush will IRREVERSIBLY DESTROY all data, but not change tables in database.
South: http://south.aeracode.org/
Django 1.7: https://docs.djangoproject.com/en/dev/releases/1.7/#django-1-7-release-notes-under-development
you should also notice that if you only need an id field, class Song has a default AutoField id, just use song.id Django models Quick Example

Related

Use Django Migrations to delete a table

I am moving from Rails to Django and have an existing database. I created models.py via python manage.py inspectdb > models.py, made changes, and tested some endpoints. Everything seems fine.
I then ran python manage.py makemigrations and migrate to make the initial django mirgation.
I noticed an old Rail's specific Model / table called ArInternalMetadata / ar_internal_metadata. I figure I could easily remove the table by simply removing the model from models.py and rerun makemigrations however when I do that, django just says No changes detected. Running migrate doesn't remove the table either.
Figured it out. When inspectdb creates Models from an existing database, it sets managed in the Meta inner class to False by default.
class AssetCategories(FacadeModel):
created_at = models.DateTimeField()
updated_at = models.DateTimeField()
name = models.CharField(max_length=255)
deleted_at = models.DateTimeField(blank=True, null=True)
class Meta:
managed = False
db_table = 'asset_categories'
Per the Django 2.1 Docs this will prevent deletion from happening
If False, no database table creation or deletion operations will be performed for this model
Removing managed = False from the Meta class allows makemigrations / migrate to delete the table.

Django Foreign Key not working

Edit:Django version 1.6.1
I keep getting this error when trying to create a RedditPost object through the admin:
no such column: subreddit_id
The subreddit_id error references RedditPost.subreddit (not Subreddit.subreddit) and then adds an _id at the end for some reason.
There's no problem with the reference. When trying to create a RedditPost from admin, the drop down menu for Subreddits shows all the available Subreddits objects.
class Subreddit(models.Model):
subreddit = models.CharField(max_length=100, primary_key=True)
title = models.CharField(max_length=100, null=False)
def __unicode__(self):
return smart_unicode(self.subreddit)
class RedditPost(models.Model):
comments_link = models.CharField(max_length=256, primary_key=True)
submitted_link = models.CharField(max_length=256, null=False)
rank = models.IntegerField(null=False)
title = models.CharField(max_length=100, null=False)
reddit_timestamp = models.DateTimeField(null=False)
updated_at = models.DateTimeField(auto_now_add=True, auto_now=True)
subreddit = models.ForeignKey('Subreddit')
RESOLVED/SOLUTION: I ended using "flush" which didn't clear up the databases when I made changes (I wasn't using any migrations). I had to use:
python manage.py sqlclear "app_name" | python manage.py dbshell
To completely clear the database and then I had to follow this link(Django South error with initial migration) to do the migration correctly.
_id is automatically added by Django. there are reasions for it.
your db table RedditPost doesnot just have this column whatsoever..
after changing the table (by adding this new column), do:
if django version < 1.7: (south needs to be installed)
python manage.py schemamigration yourapp --auto
python manage.py migrate yourapp
if django version >= 1.7:
python manage.py makemigrations
python manage.py migrate
I had the same problem. Delete your db.sqlite3 file. Then on the terminal,
python3 manage.py makemigrations
python3 manage.py migrate
That's it. But your all saved database values will be deleted.

Django - Create Category Views doesn't create Column

I am doing this tutorial tangowithdjango 5 Models and databases
In the exercises it asks to create a views and likes column with default=0 in the categories. Then to use population script to update them with values.
Direct quote from site
Update the Category model to include the additional attributes, views
and likes where the default value is zero.
So I have gone and created the categories in models.py
from django.db import models
from django.template.defaultfilters import default
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
views = models.IntegerField(default=0)
likes = models.IntegerField(default=0)
class Meta:
verbose_name_plural = "Categories"
def __unicode__(self):
return self.name
class Page(models.Model):
category = models.ForeignKey(Category)
title = models.CharField(max_length=128)
url = models.URLField()
views = models.IntegerField(default=0)
Then I sync.db
However the columns aren't creating I get this error from the view.
Exception Type: DatabaseError at /admin/rango/category/
Exception Value: no such column: rango_category.views
What is wrong with how I have created them? Do I have to remove all my database tables and recreate them?
Edit: The solution to Incorrect Duplicate doesn't resolve the issue, as well as my answer I thought would. Deleting the database and re-syncing didn't resolve the issue with creating the population script.
The sql appears to be ok I am unsure what is wrong.
BEGIN;
CREATE TABLE "rango_category" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(128) NOT NULL UNIQUE,
"views" integer NOT NULL,
"likes" integer NOT NULL
)
;
CREATE TABLE "rango_page" (
"id" integer NOT NULL PRIMARY KEY,
"category_id" integer NOT NULL REFERENCES "rango_category" ("id"),
"title" varchar(128) NOT NULL,
"url" varchar(200) NOT NULL,
"views" integer NOT NULL
)
;
COMMIT;
Finished "/home/sayth/workspace/tango_project/manage.py sql rango" execution.
Even re deleting database and redesigning and recreating models doesn't reolved.
BEGIN;
CREATE TABLE "rango_category" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(128) NOT NULL UNIQUE
)
;
CREATE TABLE "rango_page" (
"id" integer NOT NULL PRIMARY KEY,
"category_id" integer NOT NULL REFERENCES "rango_category" ("id"),
"title" varchar(128) NOT NULL,
"url" varchar(200) NOT NULL,
"views" integer NOT NULL,
"likes" integer NOT NULL
)
;
COMMIT;
Finished "/home/sayth/workspace/tango_project/manage.py sql rango" execution.
Ah yes I overlooked a warning in the doc.
Warning Whenever you add to existing database models, you will have to
delete the database file and then re-sync the database by running
python manage.py syncb again. This is a drawback of Django 1.5.4, and
can be quite frustrating. If you however add a new model, you can
syncdb your database without having to delete and recreate it. You
must therefore bear this in mind when tweaking your database: new
models will be synchronised with syncdb - but changes to existing
models will not be. When adding a new model to your application’s
models.py file, you can simply run the following command to
synchronise the database with the command $ python manage.py syncdb.
When updating an existing model to your application’s models.py file,
you must perform the following steps. Delete the database. Recreate
the database with the command $ python manage.py syncdb. Populate the
new database with data. Deleting and recreating the database from
scratch is a frustrating process. A possible solution to this issue
could be to use a third party application like South to handle
database schema migrations (changes to your models). South is
currently in active development and is considered a standard solution
for Django schema migrations until this functionality becomes part of
the standard Django codebase. We don’t cover South here - but the
official South documentation provides a handy tutorial if you’re
interested. If you don’t want to use South, we discuss a technique in
Section 5.8 to speed up the updating process. You may have also
noticed that our Category model is currently lacking some fields that
we defined in Rango’s requirements. We will add these in later to
remind you of the updating process.
And it appears migrations in core will not be available until django 1.7.
I had incorrectly updated the populate script it should have looked like.
def add_page(cat, title, url, views=0):
p = Page.objects.get_or_create(category=cat, title=title, url=url, views=views)[0]
return p
def add_cat(name, views=0, likes=0):
c = Category.objects.get_or_create(name=name, views=views, likes=likes)[0]
return c
see
https://stackoverflow.com/a/19759473/461887
django migrations

How can I tell Django to include tables for my models on a syncdb?

I suspect that I have not imported my models into some place they need to be reported for a syncdb to pick them up.
Where do I need to import my models.py (or otherwise register my models) so that Django will include them on a syncdb?
In models.py, I have:
from django.contrib.auth.models import User
from django.db import models
class CalendarEntry(models.Model):
description = models.TextField()
interval = models.IntegerField()
regular_expression = models.TextField(blank = True)
scratchpad = models.TextField()
should_hide = models.BooleanField()
user = models.ForeignKey(User)
...
When I try to run a syncdb, it doesn't create any tables; the database is empty.
christos#christos-virtual-machine:~/dashboard > python manage.py syncdb
Creating tables ...
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
christos#christos-virtual-machine:~/dashboard > sqlite3 *.db
SQLite version 3.7.15.2 2013-01-09 11:53:05
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
sqlite>
What can/should I do so that the syncdb appropriately populates the database?
Is the app in INSTALLED_APPS ?
Also note that syncdb won't populate tables. It will only create them.

Django testing: DatabaseError: no such table for ManyToManyField

I've written a couple of tests for really simple blog app, but the many to many relationship fails when I run the test: ./manage.py test myblog
DatabaseError: no such table: myblog_post_tag
Yet when I do ./manage.py sql myblog:
BEGIN;
CREATE TABLE "myblog_tag" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(50) NOT NULL
)
;
CREATE TABLE "myblog_post_tag" (
"id" integer NOT NULL PRIMARY KEY,
"post_id" integer NOT NULL,
"tag_id" integer NOT NULL REFERENCES "myblog_tag" ("id"),
UNIQUE ("post_id", "tag_id")
)
;
CREATE TABLE "myblog_post" (
"id" integer NOT NULL PRIMARY KEY,
"title" varchar(200) NOT NULL,
"pub_date" datetime NOT NULL,
"content" text NOT NULL
)
;
COMMIT;
It does create a table, yet it fails to do so while testing? Any help is appreciated.
Here's my test:
class TagModelTest(TestCase):
def test_create_tags_for_posts(self):
# tests tagging posts, postodd will have tags 1 & 3, posteven will be 2 & 4
postodd = Post(
title="testing odd tags",
pub_date=timezone.now(),
content='''hello everybody, we are testing some tagging
functionality here. This post should have odd tags.''',
)
posteven = Post(
title="test even tags",
pub_date=timezone.now(),
content ='''hello everybody, we are testing some tagging
functionality here. This post should have even tags.''',
)
#save them to db
postodd.save()
posteven.save()
# create the tags
tag1 = Tag(name="1")
tag2 = Tag(name="2")
tag3 = Tag(name="3")
tag4 = Tag(name="4")
# save all tags to db
tag1.save()
tag2.save()
tag3.save()
tag4.save()
# create the many2many relationship
postodd.tag.add(tag1)
And my models.py if needed:
from django.db import models
class Tag(models.Model):
name = models.CharField(max_length=50)
def __unicode__(self):
return self.name
class Post(models.Model):
tag = models.ManyToManyField(Tag)
title = models.CharField(max_length=200)
pub_date = models.DateTimeField(verbose_name="Date published")
content = models.TextField()
def __unicode__(self):
return self.title
./manage.py sql myblog does not execute the SQL, it just outputs what it would execute if you ran syncdb.
In this case, it seems the table is missing from your db.
If this was a result of a modification to an existing app; for example you just added a new field to your model; then running syncdb won't affect the changes to your database. syncdb doesn't do any destructive operations (like adding or dropping tables or columns).
In this case you can manually run the query to add the column; or drop and recreate your tables with syncdb.
Since this is a common problem most people use a data migration tool like south to handle these changes for you. South will manage these small changes intelligently.

Categories