Python импорт MySQLdb, внутренняя ошибка сервера Apache - PullRequest
3 голосов
/ 10 февраля 2010

У меня проблема, аналогичная описанной в " .cgi проблема с веб-сервером ", хотя я рассмотрел и протестировал ранее предложенные решения безуспешно.

Я использую ту же программу на Mac OS X 10.5.8, Apache 2.2.13, используя Python 2.6.4. Я могу успешно запустить код в оболочке python и в командной строке терминала, но я получаю <type 'exceptions.ImportError'>: No module named MySQLdb, когда пытаюсь запустить его на уровне "http://localhost/cgi-bin/test.cgi". *

#!/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. Однако, когда я запускаю его через веб-сервер, я получаю ту же ошибку. Если я закомментирую import MySQLdb в test.cgi с новым циклом for, страница не откроется.

Как мне установить PYTHONPATH в Apache? На 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 и / или разрешений ...


[редактировать] Решение:

Чтобы проверить, какую версию Python использует Apache, я добавил следующий код:

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')

Возможно, есть систематическое исправление, изменяющее PYTHONPATH в httpd.conf APACHE, но я еще не понял этого.

Ответы [ 2 ]

2 голосов
/ 10 февраля 2010

Убедитесь, что двоичный файл python, который использует Apache, имеет 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 на сломанном скрипте, это ваша проблема.

Edit:

Судя по обновлению 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.

Другой вариант - жестко закодировать путь к двоичному файлу Python в вашем test.cgi к тому же, который вы подтвердили, что используете из командной строки. В вашем скрипте у вас есть /usr/bin/env python, что является хорошей практикой. Однако, когда вы сталкиваетесь с проблемами среды и пути, такими как вы, было бы хорошей идеей жестко закодировать двоичный файл python, пока вы не преодолеете это препятствие.

Из командной строки выполните which python, чтобы определить, на какой двоичный файл Python ссылается CLI:

% 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.

1 голос
/ 28 сентября 2012

У меня тоже есть эта проблема, но я разобрался после нескольких часов попыток.

Вот мой сценарий: Мне нужно import MySQLdb в файле Python CGI, но это не удалось, и поднял ImportError.

Затем я распечатываю путь к веб-серверу и локальный путь к 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

и это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...