Django testing: DatabaseError: no such table for ManyToManyField
Asked Answered
C

1

6

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
Carlitacarlo answered 28/8, 2012 at 2:23 Comment(0)
R
1

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

Realistic answered 28/8, 2012 at 6:50 Comment(1)
But I'm not using syncdb. Right now I'm only running tests, so when I run a test, doesn't it create a testing database anyway?Carlitacarlo

© 2022 - 2024 — McMap. All rights reserved.