Сценарий Python + CGI не может получить доступ к переменным среды

Я кодирую веб-сервис на python, который использует базу данных Oracle. У меня установлен и работает cx_Oracle, но у меня возникают некоторые проблемы, когда я запускаю свой код Python как CGI с использованием Apache.

Например, следующий код отлично работает в командной строке:

#!/usr/bin/python 
import os 
import cx_Oracle 
import defs as df 

os.putenv('ORACLE_HOME', '/oracledb/10.2.0/') 
os.putenv('LD_LIBRARY_PATH', '/oracledb/10.2.0/lib') 

con = cx_Oracle.Connection(df.DB_USER, df.DB_PASS, df.DB_SID) 
print con

Но когда я запускаю его как CGI, я получаю сообщение «cx_Oracle.InterfaceError: невозможно получить дескриптор среды Oracle» в журнале ошибок apache.

Я искал в сети, и все говорят, что я должен установить переменные среды ORACLE_HOME и LD_LIBRARY_PATH. Каким-то образом сценарий CGI не может получить доступ к этим переменным среды, даже когда я определяю их с помощью os.putenv, как вы можете видеть в коде.

Что я делаю неправильно? Спасибо!


person ametade    schedule 01.07.2009    source источник
comment
Почему вы не используете mod_wsgi?   -  person S.Lott    schedule 01.07.2009


Ответы (9)


Это работает для меня:

os.putenv('ORACLE_HOME', '/oracle/client/v10.2.0.3-64bit')
os.putenv('LD_LIBRARY_PATH', '/oracle/client/v10.2.0.3-64bit/lib')
os.environ['ORACLE_HOME'] = '/oracle/client/v10.2.0.3-64bit'
os.environ['LD_LIBRARY_PATH'] = '/oracle/client/v10.2.0.3-64bit/lib'

Учтите, что сначала putenv, а затем обновите environ.

person dmitry    schedule 22.03.2011

Ты нуждаешься в этом:

os.environ['ORACLE_HOME'] = '/oracledb/10.2.0/'
os.environ['LD_LIBRARY_PATH'] = '/oracledb/10.2.0/lib'

вместо использования os.putenv(), потому что os.putenv() не обновляет os.environ, на который предположительно смотрит cx_Oracle.

Документация: Прочие интерфейсы операционной системы говорит: "Примечание. Вызов putenv() напрямую не изменяет os.environ, поэтому лучше изменить os.environ."

person RichieHindle    schedule 01.07.2009
comment
Попробуйте объединить это решение и от eduffy? - person RichieHindle; 01.07.2009
comment
Нет. Это действительно странная проблема. Если я добавлю print os.environ, я получу ORACLE_HOME и LD_LIBRARY_PATH, определенные в словаре. Может ли это быть проблемой конфигурации apache? - person ametade; 01.07.2009
comment
Я предполагаю, что помимо этих двух переменных окружения недостает еще одного элемента. Либо другая отсутствующая переменная среды, либо проблема с правами доступа. Попробуйте использовать setuid в своем CGI-скрипте, чтобы запустить его от имени того же пользователя, что и ваш тест командной строки (не то, чтобы я рекомендовал это для производства!, но это может помочь изолировать проблему). - person RichieHindle; 01.07.2009

Не забудьте добавить модуль env для apache:

a2enmod env

в конфигурации .htaccess или apache:

SetEnv LD_LIBRARY_PATH /oracle_lib_path

в /etc/apache2/envvars не работает

person ZiTAL    schedule 24.01.2012

Вы можете полностью устранить проблему, если избавитесь от необходимости устанавливать переменные среды. Вот примечание о том, как это сделать, установив Oracle Instant Client на свой компьютер.

установка Oracle Instantclient в Linux без установки переменных среды?

person Mark Harrison    schedule 03.07.2009

Мне удалось решить проблему.

Каким-то образом пользователь и группа, которые использовал apache, не имели доступа к переменным среды. Я решил проблему, изменив пользователя и группу, которую использовал apache, на пользователя, который, как я уверен, имел доступ к этим переменным.

Странно (и разочаровывает), что так сложно установить эти переменные с помощью Python.

Спасибо всем, кто ответил на мой вопрос!

person ametade    schedule 17.07.2009

Из краткого google проблемы , возможно, ваша проблема связана с окончанием / в ORACLE_HOME.
Попробуйте удалить его (а также воспользоваться советом Ричи) и посмотрите, сработает ли оно.

person rob    schedule 01.07.2009

Вы можете использовать сценарий оболочки для реализации CGI, установить переменные среды в сценарии оболочки и вызвать сценарий python из сценария оболочки.

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

person Aaron Watters    schedule 01.07.2009

Собственно вопрос, почему код вопрошающего не работал, еще не получил ответа.

Ответ заключается в том, что переменная среды LD_LIBRARY_PATH оценивается только при запуске приложения (в данном случае интерпретатора Python). Когда Python запущен, уже слишком поздно возиться с этой переменной; и совершенно не имеет значения, устанавливаете ли вы его с помощью os.environ или os.putenv (но обычно следует использовать первый).

Решение состоит в том, чтобы установить переменную среды LD_LIBRARY_PATH в сценарии-оболочке, который запускает сценарий Python, или запустить Apache с уже установленной переменной среды. В OpenSUSE вы можете сделать последнее, например, установив LD_LIBRARY_PATH в /etc/sysconfig/apache2.

Кстати, та же проблема возникает при использовании mod_wsgi вместо CGI-скрипта. См. раздел «Не удается найти общую библиотеку Python» на странице mod_wsgi Проблемы установки. .

person Cito    schedule 30.11.2011

Ваши заявления не по порядку?

#!/usr/bin/python 
import os 
os.putenv('ORACLE_HOME', '/oracledb/10.2.0/') 
os.putenv('LD_LIBRARY_PATH', '/oracledb/10.2.0/lib') 

import cx_Oracle 
import defs as df 

con = cx_Oracle.Connection(df.DB_USER, df.DB_PASS, df.DB_SID) 
print con
person eduffy    schedule 01.07.2009