Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 420
binarymac Avatar asked Aug 28 '12 02:08

binarymac


1 Answers

./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.

like image 78
Burhan Khalid Avatar answered Oct 27 '22 00:10

Burhan Khalid