我需要运行一个 manage.py loaddata 命令将一些数据导入我的 heroku 实例的数据库中,而 heroku 的 ethereal 文件系统在这方面存在一些问题。我真的不希望将数据文件添加到我的heroku存储库并在每次我想运行loaddata时推送更新(因为我需要定期为不同的heroku实例运行不同的文件相同的代码库。)有没有办法a)在远程实例上运行 loaddata 而无需将数据文件驻留在实例的文件系统上,可能是通过管道传输数据或引用本地文件,或者 b) 上传文件并在同一会话中运行 loaddata,以便在执行命令时文件可以存在于实例上?(我意识到它会在交互式会话结束后立即消失)
4 回答
(……几年后)
@Ben Roberts 的方法是明智的,但请注意,几年后,所有障碍都已修复:
- Django 加载数据现在接受来自标准输入的输入,使用
-
- Heroku 运行命令管道已修复(Ben 链接的问题现已关闭)
因此,您不需要自定义管理命令。从本地文件加载数据到 Heroku 现在应该很简单:
$ cat your-data-file.json | heroku run --no-tty -a <your-app> -- python manage.py loaddata --format=json -
奖励:对于相等和相反的动作,您可以使用此处的答案转储数据。
[编辑:--no-tty
感谢@rgov添加选项]
这是 a 想出的(使用我的(a)想法和来自标准输入的管道),但由于 heroku 运行的这个问题它不起作用:https ://github.com/heroku/heroku/issues/256
用于包装 loaddata 以使其使用标准输入的管理命令(如果您设置了 django eviron,则可以将其编写为 python 脚本):
# someapp/management/commands/loaddata_stdin.py
import os
import sys
from django.core.management import BaseCommand, call_command
class Command(BaseCommand):
def transfer_stdin_to_tempfile(self):
content = sys.stdin.read() # could use readlines if content is expected to be huge
outfile = open ('temp.json', 'w')
outfile.write(content)
outfile.close()
return outfile.name
def handle(self, *args, **options):
tempfile_name = self.transfer_stdin_to_tempfile()
call_command('loaddata', tempfile_name, traceback=True )
os.remove(tempfile_name)
用法:
$ cat some_dump.json | heroku run python manage.py loaddata_stdin.py
Heroku 的PG Backups 插件可以帮助您解决这个问题(也许去年这个时候还不存在):https ://devcenter.heroku.com/articles/heroku-postgres-import-export
本教程以相当简单的术语描述了如何使用pg_dump
创建 sql 转储(在此处添加命令以防链接更改):
$ pg_dump -Fc --no-acl --no-owner -h localhost -U <your username> mydb > mydb.dump
我亲自上传mydb.dump
到 Dropbox 文件夹,然后运行 pgbackups 命令:
$ heroku pgbackups:restore <database url> '<url for mydb.dump>'
我尝试了您的方法并且它有效,但是随着文件大小变大遇到了一些问题。
或者您可以loaddata
访问本地数据库,然后:
heroku pg:push mylocaldb HEROKU_POSTGRESQL_MAGENTA --app sushi
文档:https ://devcenter.heroku.com/articles/heroku-postgresql#pg-push