Python导入MySQLdb,Apache内部服务器错误

时间:2010-02-09 21:09:03

标签: python cgi

我遇到与“.cgi problem with web server”中描述的类似的问题,尽管我检查并测试了之前建议的解决方案但没有成功。

我正在使用Python 2.6.4在Mac OS X 10.5.8,Apache 2.2.13上运行相同的程序。我可以在python shell和终端命令行中成功运行代码,但当我尝试在“http://localhost/cgi-bin/test.cgi”运行它时,我得到<type 'exceptions.ImportError'>: No module named MySQLdb。如果我发表评论import MySQLdb,它会成功运行。

#!/usr/bin/env python
import cgitb
cgitb.enable() 
import MySQLdb

print "Content-Type: text/html"
print
print "<html><head><title>Books</title></head>"
print "<body>"
print "<h1>Books</h1>"
print "<ul>"

connection = MySQLdb.connect(user='me', passwd='letmein', db='my_db')
cursor = connection.cursor()
cursor.execute("SELECT name FROM books ORDER BY pub_date DESC LIMIT 10")

for row in cursor.fetchall():
    print "<li>%s</li>" % row[0]

print "</ul>"
print "</body></html>"

connection.close()

[edit] 根据第一个答案:

如果我按照指定修改test.cgi并从终端命令行运行它,MySQLdb的目录将显示在sys.path中。但是,当我通过Web服务器运行它时,我得到了同样的错误。如果我使用新的for循环在import MySQLdb中注释掉test.cgi,则该页面无法打开。

如何设置Apache的PYTHONPATH?在python shell中,我尝试了:

import MySQLdb
import os
print os.path.dirname(MySQLdb.__file__)

然后,基于其他帖子,我尝试在原始test.cgi中添加结果路径:

import sys
sys.path.append('/Library/Frameworks/Python.framework/Versions/6.0.0/lib/python2.6/site-packages/MySQL_python-1.2.3c1-py2.6-macosx-10.5-i386.egg/')

但这产生了同样的错误。


[编辑]

不幸的是,两种解决方案都没有效添加sys.path的路径给了我与以前相同的错误。对python二进制文件#!/Library/Frameworks/Python.framework/Versions/Current/bin/python的路径进行硬编码会产生一个冗长的错误,其中一部分会显示出来:

A problem occurred in a Python script. Here is the sequence of function calls leading up to the error, in the order they occurred.

 /Library/WebServer/CGI-Executables/test.cgi in ()
   15 #sys.path.append('/Library/Frameworks/Python.framework/Versions/6.0.0/lib/python2.6/site-packages/')
   16 
   17 import MySQLdb
   18 #import _mysql
   19 
MySQLdb undefined
 /Library/WebServer/CGI-Executables/build/bdist.macosx-10.5-i386/egg/MySQLdb/__init__.py in ()
 /Library/WebServer/CGI-Executables/build/bdist.macosx-10.5-i386/egg/_mysql.py in ()
 /Library/WebServer/CGI-Executables/build/bdist.macosx-10.5-i386/egg/_mysql.py in __bootstrap__()
 /Library/Frameworks/Python.framework/Versions/6.0.0/lib/python2.6/site-packages/pkg_resources.py in resource_filename(self=<pkg_resources.ResourceManager instance at 0x3c8a80>, package_or_requirement='_mysql', resource_name='_mysql.so')
  848         """Return a true filesystem path for specified resource"""
  849         return get_provider(package_or_requirement).get_resource_filename(
  850             self, resource_name
  851         )
  852 
self = <pkg_resources.ResourceManager instance at 0x3c8a80>, resource_name = '_mysql.so'

...

<class 'pkg_resources.ExtractionError'>: Can't extract file(s) to egg cache The following error occurred while trying to extract file(s) to the Python egg cache: [Errno 13] Permission denied: '/Library/WebServer/.python-eggs' The Python egg cache directory is currently set to: /Library/WebServer/.python-eggs Perhaps your account does not have write access to this directory? You can change the cache directory by setting the PYTHON_EGG_CACHE environment variable to point to an accessible directory. 
      args = ("Can't extract file(s) to egg cache\n\nThe followin...nt\nvariable to point to an accessible directory.\n",) 
      cache_path = '/Library/WebServer/.python-eggs' 
      manager = <pkg_resources.ResourceManager instance at 0x3c8a80> 
      message = "Can't extract file(s) to egg cache\n\nThe followin...nt\nvariable to point to an accessible directory.\n" 
      original_error = OSError(13, 'Permission denied')

这个错误似乎意味着它可能与设置PYTHON_EGG_CACHE和/或权限有关......


[edit] 解决方案:

为了测试Apache正在使用哪个版本的Python,我添加了以下代码:

import sys
version = sys.version
path = sys.path

...

print "<h1>%s</h1>" % version                                                                  
print "<h1>%s</h1>" % path

表明Apache确实使用了制造商安装的Python 2.5.1,而不是Python 2.6.4和相关的MySQLdb模块。因此,将以下代码添加到原始test.cgi修复了问题:

import os
os.environ['PYTHON_EGG_CACHE'] = '/tmp'
import sys
sys.path.append('/Library/Frameworks/Python.framework/Versions/6.0.0/lib/python2.6/site-packages/MySQL_python-1.2.3c1-py2.6-macosx-10.5-i386.egg')

通过改变APACHE的httpd.conf中的PYTHONPATH可能会有一个系统的修复,但我还没有想出来。

2 个答案:

答案 0 :(得分:2)

确保Apache正在使用的python二进制文件MySQLdb中包含PYTHONPATH

通过在工作脚本中检查MySQLdb的位置来确认它:

import os
print os.path.dirname(MySQLdb.__file__)

并将其与sys.path内的test.cgi的输出进行比较:

import sys
for p in sys.path: 
    print p + "<br/>"

如果工作脚本中的MySQLdb目录不在sys.path的破损脚本中,那就有问题了。

修改

根据对OP的更新,您需要添加到PYTHONPATH的目录看起来像/Library/Frameworks/Python.framework/Versions/6.0.0/lib/python2.6/site-packages/。您使用的另一条路径:

/Library/Frameworks/Python.framework/Versions/6.0.0/lib/python2.6/site-packages/MySQL_python-1.2.3c1-py2.6-macosx-10.5-i386.egg/

...是已安装的.egg的位置。我讨厌.egg安装这个原因,因为它可能会让人感到困惑,尤其是那些对Python不太新的人。

另一种选择是将test.cgi中Python二进制文件的路径硬编码到您已从命令行确认使用的路径。在你的脚本中你有/usr/bin/env python,这是一个很好的做法。但是,当你遇到像你这样的环境和路径问题时,硬编码python二进制文件可能是个好主意,直​​到你能够克服这个障碍。

从命令行执行which python,以确定CLI引用的python二进制文件:

% which python
/opt/local/bin/python 

我的python二进制文件的路径是/opt/local/bin/python。如果那是你的,请将/usr/bin/env python替换为test.cgi

中的#!/opt/local/bin/python import cgitb # ... and so on ...
ImportError

这样做之后,你还在收到/Library/Frameworks/Python.framework/Versions/6.0.0/lib/python2.6/site-packages/吗?如果是这样,你就缩小了问题的范围。将sys.path添加到{{1}}可以解决您的问题,而无需对python二进制文件的路径进行硬编码。

答案 1 :(得分:1)

我也遇到了这个问题,但经过几个小时的努力,我想出来了。

以下是我的方案:我需要在Python cgi文件中import MySQLdb,但它失败了,并提出了ImportError

然后我打印出Web服务器路径和本地python路径,它们是:

网络服务器路径

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages
/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload
/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC

<强> /Library/Python/2.7/site-packages

和Python路径:

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/distribute-0.6.25-py2.7.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pydelicious-0.6-py2.7.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/feedparser-5.1.2-py2.7.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/googlemaps-1.0.2-py2.7.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/MySQL_python-1.2.3-py2.7-macosx-10.5-intel.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/elementtree-1.2.7_20070827_preview-py2.7.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/oauth2-1.5.170-py2.7.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/httplib2-0.7.4-py2.7.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/simplejson-2.1.6-py2.7-macosx-10.5-intel.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/python_twitter-0.8.3-py2.7.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/South-0.7.6-py2.7.egg
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pyfb-0.4.1-py2.7.egg
/usr/local/lib/wxPython-ansi-2.8.12.1/lib/python2.7/site-packages
/usr/local/lib/wxPython-ansi-2.8.12.1/lib/python2.7/site-packages/wx-2.8-mac-ansi
/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PIL
/usr/local/lib/wxPython-ansi-2.8.12.1/lib/python2.7

<强> /Library/Python/2.7/site-packages

它们都有路径/Library/Python/2.7/site-packages,显然,这是安装第三方软件包的路径,但它是空的。

为什么?

我可以在本地python环境中使用其他软件包很好地运行Python脚本,然后我注意到所有这些软件包都安装在

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/

当我在网络服务器上运行cgi文件时,服务器无法找到上述路径,当然import MySQLdb失败。

我在这里做的是复制

中的文件
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/"

/Library/Python/2.7/site-packages

它有效。