【问题标题】:Errors running geodjango based apps on heroku在 heroku 上运行基于 geodjango 的应用程序时出错
【发布时间】:2012-07-19 13:00:39
【问题描述】:

问题

我正在尝试将我的 geodjango 应用程序部署到 Heroku。应用程序运行,但是当我尝试查看/admin/world/worldborder/ (the wolrd geodjango tutorial application) 或我自己的自定义 Spots 应用程序(使用 geodjango)时,站点崩溃。

如果我查看我的heroku logs,我会看到测功机出现 500 错误:

2012-07-20T08:16:23+00:00 heroku[router]: GET myapp.herokuapp.com/admin/spots/spot/ dyno=web.1 queue=0 wait=0ms service=654ms status=500 bytes=4922

然后我通过电子邮件收到此错误:

AttributeError: 'module' object has no attribute 'GeoSQLCompiler'

完整的回溯可以在here找到

我的数据库服务器位于其他地方的 aws ec2 实例上,并且在该服务器上通过了these installation instructions

应用上下文

Django==1.4 gunicorn==0.14.2

我使用以下内容创建了我的 heroku 应用程序

heroku create myapp --stack cedar --buildpack http://github.com/cirlabs/heroku-buildpack-geodjango/

如您所见,我使用custom buildpack 来安装geodjango 所需的所有东西。如果我不使用这个自定义 buildpack 而只是使用heroku create myapp,那么我会得到this long error

我也将这些添加到 heroku 配置变量中

GEOS_LIBRARY_PATH='/app/.geodjango/geos/lib/libgeos_c.so'
GDAL_LIBRARY_PATH='/app/.geodjango/gdal/lib/libgdal.so'

我已经尝试过了

我用谷歌搜索了这个错误,只发现了一篇帖子here。基本上说要确保我的数据库后端正确设置为使用(我已经这样做了)

'ENGINE': 'django.contrib.gis.db.backends.postgis',

我也试过改成以下:

GEOS_LIBRARY_PATH='/myapp/.geodjango/geos/lib/libgeos_c.so'
GDAL_LIBRARY_PATH='/myapp/.geodjango/gdal/lib/libgdal.so'

这个应用程序在我的本地开发机器上运行良好,python manage.py runserverforeman start -f Profile.dev

为什么我不能在 Heroku 上使用基于 geodjango 的应用程序,我该如何解决这个问题?

【问题讨论】:

  • 你解决过这个问题吗?
  • 不,我没有。最后,我将我的 Web 应用程序移至 DotCloud。 docs.dotcloud.com/0.4/tutorials/python/geodjango
  • Heroku 对于 GeoDjango 应用程序来说似乎是半生不熟的。您对点云有何看法?
  • 很高兴。在经历了痛苦之后,我尝试在 Heroku DotCloud 上部署我的应用程序是小菜一碟。从字面上看,刚刚完成了他们的小教程,中提琴它已经启动并运行了。事实上,我将所有的网络应用程序都移到了 DotCloud。唯一的问题是,我认为 Heroku 免费层要好一些,但甚至没有那么多功能。
  • 它支持PostGIS吗?

标签: django heroku geodjango


【解决方案1】:

我有 93.2% 的把握确定这是path 问题。 Web 开发中的主要PITAs 之一是您的命令行环境可能与服务器的 环境几乎没有共同之处。

当我需要确切地知道从哪个目录加载了哪些模块的哪个版本时,我会使用以下内容。它返回一个 2 元组列表 ('name', 'path-to-module')。在初始化完成后调用此函数,或者在您尝试加载地理模块(或其他同样有趣的地方)之前和/或之后调用它,并将结果转储到屏幕或日志文件中。

我不知道这会解决你的问题,但它可能会给你一些有趣的见解。

注意:您可以编辑(或注释掉)re.sub()s 来品尝。我只是把它们放进去,因为一大页绝对路径名很难看,并且可以掩盖这样一个事实,即某些东西是从系统的副本而不是您自己的副本加载的。

modulelist.py

import sys, re, os
import django

def ModuleList():
    ret = []
    dir_project = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
    project_name = os.path.basename(dir_project)

    for k,v in sys.modules.items():

        x = str(v)
        if 'built-in' in x:
            ret.append((k, 'built-in'))
            continue

        m = re.search(r"^.*?'(?P<module>.*?)' from '(?P<file>.*?)'.*$", x)
        if m:
            d = m.groupdict()
            f = d['file']
            f = re.sub(r'/usr/.*?/lib/python[.0-9]*/site-packages/django/', 'system django >> ', f)
            f = re.sub(r'/usr/.*?/lib/python[.0-9]*/site-packages/', 'site-packages >> ', f)
            f = re.sub(r'/usr/.*?/lib/python[.0-9]*/', 'system python >> ', f)
            f = re.sub(dir_project+'.*python/', 'local python >> ', f)
            f = re.sub(dir_project+'.*django/', 'local django >> ', f)
            f = re.sub(dir_project+r'(/\.\./)?', project_name + ' >> ', f)
            ret.append((d['module'], f))
    ret.sort( lambda a,b: cmp(a[0].lower(), b[0].lower()) )
    ret.insert(0, ('Python version', sys.version) )
    ret.insert(0, ('Django version', django.get_version()) )

    return ret
# ModuleList

if __name__ == "__main__":
    for x in ModuleList():
        print "%s\t%s" % (x[0], x[1])

【讨论】:

  • 嗨,彼得,我明白你在说什么。我会尝试弹出这段代码,看看会发生什么。即使我点击了管理员中的链接以转到应用程序更改列表,但我得到了我的错误。现在确定如何将它挂在那里,但也许我会制作另一个更简单的视图并将这段代码放在那里看看会发生什么。
  • 在 Django 站点中,您的模块列表通常不会在执行一个或另一个路径时发生太大变化。唯一的例外是出现在嵌套块/def 中的import。所以你可以从创建一个“玩具视图”开始,它只是转储这个例程的输出。这应该可以让您初步了解事物所在的位置。祝你好运!
猜你喜欢
  • 2013-09-23
  • 2012-09-08
  • 2017-05-05
  • 2015-07-03
  • 1970-01-01
  • 2016-10-20
  • 2012-12-17
  • 2014-11-03
  • 1970-01-01
相关资源
最近更新 更多