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

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

我正在使用Python 2.6.4在Mac OS X 10.5.8,Apache 2.2.13上运行相同的程序.我可以在python shell和终端命令行中成功运行代码,但是我得到< type'exceptions.ImportError'&gt ;:尝试在“ http://localhost/cgi-bin/test.cgi”运行时,没有名为MySQLdb的模块.如果我注释掉导入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并从终端命令行运行它,则sys.path中将显示MySQLdb的目录.但是,当我通过Web服务器运行它时,出现了相同的错误.如果我用新的for循环注释掉test.cgi中的import MySQLdb,页面将无法打开.

如何设置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和/或权限有关.

[编辑]解决方案:

为了测试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模块的Python 2.6.4.因此,将以下代码添加到原始的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进行系统修复,但我还没有弄清楚.

解决方法:

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

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

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

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

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二进制代码进行硬编码,直到可以克服此障碍.

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

% which python
/opt/local/bin/python 

我的python二进制文件的路径是/ opt / local / bin / python.因此,如果这是您的,请用test.cgi中的/usr/bin/env python替换它:

#!/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二进制文件的路径.

上一篇:Python CGI脚本:OSError:[Errno 8] Exec格式错误


下一篇:PHP 是怎么接收到请求的?