在Heroku上使用Django:关系不存在

15

我使用 sqlite3 作为默认数据库,在本地构建了一个 Django 1.9 项目。我的应用程序名为 Download,其中在 models.py 中定义了 DownloadedSongs 表:

models.py

from __future__ import unicode_literals
from django.db import models


class DownloadedSongs(models.Model):
    song_name = models.CharField(max_length = 255)
    song_artist = models.CharField(max_length = 255)

    def __str__(self):
        return self.song_name + ' - ' + self.song_artist

现在,为了将我的本地项目部署到Heroku,我在我的settings.py文件底部添加了以下行:

import dj_database_url
DATABASES['default'] =  dj_database_url.config()

我的应用程序有一个表单,其中包含几个文本字段。在提交该表单后,数据将插入DownloadedSongs表中。现在,当我在Heroku上部署我的项目并尝试提交此表单时,我收到以下错误:

Exception Type: ProgrammingError at /download/
Exception Value: relation "Download_downloadedsongs" does not exist
LINE 1: INSERT INTO "Download_downloadedsongs" ("song_name", "song_a...

这是我的requirements.txt文件的内容:

beautifulsoup4==4.4.1
cssselect==0.9.1
dj-database-url==0.4.1
dj-static==0.0.6
Django==1.9
django-toolbelt==0.0.1
gunicorn==19.6.0
lxml==3.6.0
psycopg2==2.6.1
requests==2.10.0
static3==0.7.0

另外,我也尝试运行了以下命令:

heroku run python manage.py makemigrations
heroku run python manage.py migrate

然而,问题仍然存在。这里似乎出了什么问题?


你能够访问数据库以查看表名吗?这可能是因为表名全是小写字母吗?还是你仍然需要运行syncdb命令? - Furbeenator
syndb 命令在 Django 1.9 中已被弃用。但我确保运行了 makemigrations 命令。 - Manas Chaturvedi
5个回答

15

确保本地迁移文件夹和内容都在Git版本控制下。

如果没有,请按照以下步骤添加、提交和推送它们(假设您有一个位于<myapp>下的迁移文件夹,并且您的Git远程称为“heroku”):

git add <myapp>/migrations/*
git commit -m "Fix Heroku deployment"
git push heroku

等待推送成功并收到本地提示后再执行登录Heroku并执行迁移操作。 要在一个执行环境中完成此操作,请勿将其作为单个Heroku命令启动,而是启动Bash shell并在其中执行这两个命令:(不要输入“〜$”,它代表Heroku提示符)

heroku run bash
~$  ./manage.py migrate
~$  exit

4
在测试过程中,我遇到了一个问题,需要登录到shell以执行迁移。我按照上述步骤操作,但是我使用了"python manage.py"而不是"./manage.py"(使用"./"会导致权限错误)。谢谢。 - aleksk

8

您不应该通过 heroku run 命令来运行 makemigrations。您需要在本地运行此命令,并将结果提交到 git。然后,您可以部署该代码并通过 heroku run python manage.py migrate 命令来运行这些生成的迁移。

原因是每次使用 heroku run 命令时都会启动一个新的 dyno,具有新的文件系统,因此第一个命令中生成的任何迁移都会在第二个命令运行时丢失。但无论如何,迁移都是您的代码的一部分,并且必须在版本控制中。


1
作为Heroku的dynos没有跨部署持久化的文件系统,像SQLite3这样的基于文件的数据库是不适合的。但它是开发/快速原型的好DB。在部署期间,您的整个SQLite数据库将被清除,我认为您应该在部署到Heroku时转向专用数据库。我知道Heroku有一个免费的Postgres数据库层,如果您只想测试部署到Heroku,我会推荐使用。https://dev59.com/B10Z5IYBdhLWcg3wfgYR#31395988

1
python manage.py makemigrations
python manage.py migrate
python manage.py migrate --run-syncdb

这对我很有帮助。

0

我知道这已经过时了,但我遇到了这个问题,并发现this thread很有用。

总之,当执行迁移(应该在数据库中创建所需的关系)时,错误也可能出现,因为Django的最新版本在执行迁移之前会检查您的urls.py。在我的情况下 - 以及许多其他人的情况,加载urls.py意味着加载视图,并且一些视图是基于类的,并通过get_object_or_404定义了一个属性:

class CustomView(ParentCustomView):
    phase = get_object_or_404(Phase, code='C')

这是在迁移实际运行之前进行评估并导致错误的内容。我通过将视图属性转换为属性来修复它:

class CustomView(ParentCustomView):
    @property
    def phase(self):
        return get_object_or_404(Phase, code='C')

如果你遇到这个问题,很容易就能知道,因为Traceback会指向有问题的视图。

此外,在开发过程中可能不会出现这个问题,因为在创建视图之前已经进行了迁移。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接