我遇到了类似于“.cgi problem with web server”中描述的问题,尽管我回顾并测试了之前建议的解决方案,但没有成功。
我在MacOSX10.5.8和Apache2.2.13上运行相同的程序,使用的是Python2.6.4。我可以在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()

[编辑]根据第一个答案:
如果按照指定修改test.cgi并从终端命令行运行,则MySQLdb的目录将显示在sys.path中。但是,当我通过web服务器运行它时,我会得到同样的错误。如果我用新的for循环注释掉import MySQLdb中的test.cgi,页面将无法打开。
如何设置阿帕奇的蟒蛇?在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二进制文件的路径进行硬编码会产生一个冗长的错误,其中一部分如下所示:
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_缓存和/或权限有关。。。
[编辑]解决方案:
为了测试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,而不是带有相关MySQLdb模块的python2.6.4。因此,在原来的#!/Library/Frameworks/Python.framework/Versions/Current/bin/python中添加以下代码解决了问题:
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可能是一个系统性的解决方案,但我还没有找到答案。

最佳答案

确保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可以解决您的问题,而无需硬编码python二进制文件的路径。

07-24 09:52
查看更多