异常错误

在我的机器上安装 GeoDjango。我对 Python 真的很陌生,并且被带入了一个对其他团队成员来说非常棘手的安装项目。我使用 brew 安装了 Python 2.7和 GEOS,并运行了 PSQL 9.2.4,但是当我试图让 webserver 运行时仍然出现这个错误:

__import__(name)
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geometry/backend/geos.py", line 1, in <module>
from django.contrib.gis.geos import (
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geos/__init__.py", line 6, in <module>
from django.contrib.gis.geos.geometry import GEOSGeometry, wkt_regex, hex_regex
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geos/geometry.py", line 14, in <module>
from django.contrib.gis.geos.coordseq import GEOSCoordSeq
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site-
packages/django/contrib/gis/geos/coordseq.py", line 9, in <module>
from django.contrib.gis.geos.libgeos import CS_PTR
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site-
packages/django/contrib/gis/geos/libgeos.py", line 119, in <module>
_verinfo = geos_version_info()
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geos/libgeos.py", line 115, in geos_version_info
if not m: raise GEOSException('Could not parse version info string "%s"' % ver)
django.contrib.gis.geos.error.GEOSException: Could not parse version info string
"3.4.2-CAPI-1.8.2 r3921"

在 SO 或网络上似乎找不到任何与这个线索相关的东西。我想可能是正则表达式失败?我目前正在尝试重新安装 PSQL 和 GEOS,看看是否可以让它运行。

这是我的要求文件:

django==1.4
psycopg2==2.4.4
py-bcrypt==0.4
python-memcached==1.48
south==0.7.3


# Debug Tools
sqlparse==0.1.3
django-debug-toolbar==0.9.1
django-devserver==0.3.1


# Deployment
fabric==1.4


# AWS
# boto==2.1.1
django-storages==1.1.4
django-ses==0.4.1


# ECL
http://packages.elmcitylabs.com/ecl_django-0.5.3.tar.gz#ecl_django
http://packages.elmcitylabs.com/ecl_google-0.2.14.tar.gz#ecl_google
# https://packages.elmcitylabs.com/ecl_tools-0.3.7.tar.gz#ecl_tools
# https://packages.elmcitylabs.com/chargemaster-0.2.19.tar.gz
# https://packages.elmcitylabs.com/ecl_facebook-0.3.12.tar.gz#ecl_facebook
# https://packages.elmcitylabs.com/ecl_twitter-0.3.3.tar.gz#ecl_twitter


# Search
#https://github.com/elmcitylabs/django-haystack/tarball/issue-522#django-haystack
-e git+https://github.com/toastdriven/django-haystack.git#egg=django-haystack


pysolr==2.1.0-beta
# whoosh==2.3.2


# Misc
# PIL
# django-shorturls==1.0.1
# suds==0.4


django-mptt
sorl-thumbnail


stripe
pytz==2013b
26797 次浏览

这就是我的解决方案(显然它很难看,就像我的英语一样,但很管用)。 问题是版本字符串在正则表达式中有一个不需要的空白。

错误显示:

GEOSException: 无法解析版本信息字符串“3.4.2-CAPI-1.8.2 r3921”

而 geos _ version _ info 警告说:

正则表达式应该能够解析版本字符串,如 ‘3.0.0rc4-CAPI-1.3.3’、‘3.0.0-CAPI-1.4.1’或‘3.4.0dev-CAPI-1.8.0’

编辑这个文件: site-package/django/Contrib/gis/geos/libgeos.py

查找函数: geos _ version _ info

换一句台词:

ver = geos_version().decode()

用这句话:

ver = geos_version().decode().split(' ')[0]

还有另外一个问题,在末尾有一个空格,但是没有提供更多的信息。这样的版本也不匹配版本正则表达式,所以 strip()-ping 版本可能是一个快速修复的预期行为。在我的例子中是: '3.8.0-CAPI-1.13.1 '

看来去年三月左右在姜戈的 这事已经解决了。参见 姜戈虫20036。因此,升级到 Django 1.5.4将解决这个问题。

在最新的 GEOS 安装中,上面的答案不起作用... ... 但是很接近问题。

我修改了 geos _ version _ info ()上面的 regex: 来自:

version_regex = re.compile(r'^(?P<version>(?P<major>\d+)\.(?P<minor>\d+)\.(?P<subminor>\d+))((rc(?P<release_candidate>\d+))|dev)?-CAPI-(?P<capi_version>\d+\.\d+\.\d+)$')

待定:

version_regex = re.compile(r'^(?P<version>(?P<major>\d+)\.(?P<minor>\d+)\.(?P<subminor>\d+))((rc(?P<release_candidate>\d+))|dev)?-CAPI-(?P<capi_version>\d+\.\d+\.\d+).*$')

注意添加到正则表达式末尾的. * 。

我想这个问题又出现了,最近我们的 FreeBSD 服务器升级导致了这个错误:

django.contrib.gis.geos.error.GEOSException: Could not parse version info string "3.6.2-CAPI-1.10.2 4d2925d6"

看起来 Django 的 libgeos.py中的正则表达式需要再次更新,以适应这种不同的语法。Nachopro 的解决方案仍然是一个变通方案。

这个问题可以通过以下方法解决,

啤酒开关 Geos 3.6.1

对于那些之前没有安装3.6.1的用户:

  1. brew unlink geos
  2. brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/145b22e8330e094ee148861e72e26c03e73d34a1/Formula/geos.rb安装3.6.1。
  3. brew info geos应该显示3.6.1星级: enter image description here

我通过使用 https://postgresapp.com/downloads.html安装 PostGIS 和 Postgres 解决了这个问题。

  1. 安装 PostGIS (2.2) : brewinstall PostGIS
  2. 如果版本高于3.6.1,则取消链接 geos:
  3. 安装 Geos (3.6.1) : brewinstall https://raw.githubusercontent.com/Homebrew/homebrew-core/145b22e8330e094ee148861e72e26c03e73d34a1/Formula/geos.rb
  4. Switch geos 版本(最新版本是3.7.2,Django 1.11.3不支持) :
  5. 登录到数据库并创建 postgis 扩展: CREATE EXTENION postgis; 测试 postgis 扩展: SELECT ST _ Range (‘ LINESTRING (- 122.3347.606,0.051.5)’: : Geographic,‘ POINT (- 21.9664.15)’: : Geographic) ;
  6. 检查 PostGIS 版本: SELECT PostGIS _ full _ version () ;

Brew 刚刚发布了 geos 3.8.0,当然又打破了 Django 1.11。 以前的版本,3.7.3,是非常有帮助的清除所有新的全自动清理现在运行的升级,所以没有 brew switch geos 3.7.3对我来说。

我最终使用 这篇文章来了解如何查找以前的版本号和提交散列:

cd $( brew --prefix )/Homebrew/Library/Taps/homebrew/homebrew-core
git log -- Formula/geos.rb | less
# find the version you need in the file, copy its hash
brew unlink geos
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/<yourcommithash>/Formula/geos.rb

在所有这些之后,geos 3.7.3的下载由于某种原因未能通过 SHA256校验和验证... ... 所以我最终尝试了3.7.2,它确实起作用了。

目前,在 Catalina 上重新安装3.7.2的命令是:

brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/823b700ab61eeec57f34d50be2cc34a285fb5abc/Formula/geos.rb

如果一个人因为任何原因不能自己编辑网站软件包,那么这个丑陋的黑客帮我做到了,而不需要对环境本身采取行动:

try:
__import__('django.contrib.gis.geos.libgeos', fromlist=['version_regex'])
except Exception as e:
import re
att = __import__('django.contrib.gis.geos.libgeos', fromlist=['version_regex'])
setattr(att, 'version_regex', re.compile(
'^(?P<version>(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<subminor>\\d+))((rc(?P<release_candidate>\\d+))|dev)?-CAPI-(?P<capi_version>\\d+\\.\\d+\\.\\d+)( r\\d+)?( \\w+)?.*$'))
assert str(type(e)) == "<class 'django.contrib.gis.geos.error.GEOSException'>", str(e)

它是基于 JayCrossler 的回答的。

更新

上述代码执行在 django.contrib.gis.geos.__init__.py模块中找到的代码,该模块已经尝试使用有问题的部分,导致上述解决方案无法使用(对于 python 2.7 +)。这可以通过以下方式解决:

import sys
try:
import django.contrib.gis.geos.libgeos
except Exception as e:
import re
setattr(sys.modules['django.contrib.gis.geos.libgeos'],'version_regex', re.compile(
'^(?P<version>(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<subminor>\\d+))((rc(?P<release_candidate>\\d+))|dev)?-CAPI-(?P<capi_version>\\d+\\.\\d+\\.\\d+)( r\\d+)?( \\w+)?.*$'))
assert str(type(e)) == "<class 'django.contrib.gis.geos.error.GEOSException'>", str(e)

基本上,我们是直接作用于 sys.modules中的模块,而不是试图从另一个将会失败的导入获取它。