Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Как подключиться к базе в databaselibrary


(kom) #1

Connect To Database oracle.jdbc.driver.OracleDriver <дальше мои параметры подключения>

Фейлится с такой ошибкой:

ImportError: No module named oracle.jdbc.driver.OracleDriver


(Mykhailo Poliarush) #2

ну нужно установить адаптер на базу данных к которой ты будешь обращаться

какой модуль ты используешь для подключения к базе данных?


(rmerkushin) #3

Поставь cx_Orcale https://pypi.python.org/pypi/cx_Oracle

Подключаться как то так:

| Connect To Database Using Custom Params | cx_Oracle | 'oracle.jdbc.driver.OracleDriver', 'my_db_test', 'system', 's3cr3t' |

 

З.Ы.: При коннекте через cx_Oracle нужно задавать NLS_LANG, для этого можешь подправить либу DatabaseLibrary дописав перед коннектом

os.environ['NLS_LANG'] = 'American_America.AL32UTF8'. Иначе если выполнять sql скрипты с кириллицей, в бд запишется фигня.

Если лень, можешь воспользоваться этим https://github.com/rmerkushin/OracleLibrary :)

И еще один момент, DatabaseLibrary не может выполнять pl/sql.


(kom) #4

Спасибо, я даже и не знал что есть такая библиотека как OracleLibrary.

 

Что-то не получается ее установить, 

python setup.py install

 
python setup.py install
Traceback (most recent call last):
  File "setup.py", line 5, in <module>
    from OracleLibrary import __version__
ImportError: No module named OracleLibrary

(Mykhailo Poliarush) #5

да не может, но я когда дописывал лично под себя эту функцию

может кому-то понадобиться

def call_procedure(self, name, parameters):
        '''
        call stored procedure with in and out parameters 
        @param name: name of procedure
        @param parameters: parameters as tuple as example of
        ('in_value',('STRING','out_var_to_init'),('NUMBER', 'out_var_to_init'),'in_value')
        '''
        cur = None
    <span style="color: rgb(0, 136, 0); font-weight: bold;">try</span>:
        cur = <span style="color: rgb(0, 112, 32);">self</span>._dbconnection.cursor()
        <span style="color: rgb(136, 136, 136);">#process parameters</span>
        parsed_parameters = []
        <span style="color: rgb(0, 136, 0); font-weight: bold;">for</span> i, item <span style="color: rgb(0, 0, 0); font-weight: bold;">in</span> <span style="color: rgb(0, 112, 32);">enumerate</span>(parameters):
            <span style="color: rgb(0, 136, 0); font-weight: bold;">if</span> <span style="color: rgb(0, 112, 32);">str</span>(item).lower() <span style="color: rgb(0, 0, 0); font-weight: bold;">in</span> (<span style="background-color: rgb(255, 240, 240);">"string"</span>, <span style="background-color: rgb(255, 240, 240);">"number"</span>): 
                <span style="color: rgb(0, 136, 0); font-weight: bold;">exec</span> <span style="background-color: rgb(255, 240, 240);">"</span><span style="background-color: rgb(238, 238, 238);">%s</span><span style="background-color: rgb(255, 240, 240);"> = cur.var(self.db_api_2.</span><span style="background-color: rgb(238, 238, 238);">%s</span><span style="background-color: rgb(255, 240, 240);">);parsed_parameters.append(</span><span style="background-color: rgb(238, 238, 238);">%s</span><span style="background-color: rgb(255, 240, 240);">);"</span> % (item+<span style="color: rgb(0, 112, 32);">str</span>(i),item.upper(),item+<span style="color: rgb(0, 112, 32);">str</span>(i))
            <span style="color: rgb(0, 136, 0); font-weight: bold;">else</span>: 
                parsed_parameters.append(item)
        input_output = <span style="color: rgb(0, 112, 32);">tuple</span>(parsed_parameters)
        cur.callproc(name,input_output)
        <span style="color: rgb(136, 136, 136);">#backward processing to cx_Oracle.* type</span>
        parsed_parameters = []
        <span style="color: rgb(0, 136, 0); font-weight: bold;">for</span> i, item <span style="color: rgb(0, 0, 0); font-weight: bold;">in</span> <span style="color: rgb(0, 112, 32);">enumerate</span>(<span style="color: rgb(0, 112, 32);">list</span>(input_output)):
            <span style="color: rgb(0, 136, 0); font-weight: bold;">if</span> <span style="color: rgb(0, 112, 32);">isinstance</span>(item,<span style="color: rgb(0, 112, 32);">self</span>.db_api_2.NUMBER) <span style="color: rgb(0, 0, 0); font-weight: bold;">or</span> <span style="color: rgb(0, 112, 32);">isinstance</span>(item,<span style="color: rgb(0, 112, 32);">self</span>.db_api_2.STRING): 
                parsed_parameters.append(item.getvalue());
            <span style="color: rgb(0, 136, 0); font-weight: bold;">else</span>: 
                parsed_parameters.append(item)
        <span style="color: rgb(0, 112, 32);">self</span>._dbconnection.commit()
        <span style="color: rgb(0, 136, 0); font-weight: bold;">return</span> parsed_parameters
    <span style="color: rgb(0, 136, 0); font-weight: bold;">finally</span> :
        <span style="color: rgb(0, 136, 0); font-weight: bold;">if</span> cur :
            <span style="color: rgb(0, 112, 32);">self</span>._dbconnection.rollback()</pre>

 


(kom) #6

 Я скачал ojdbc7.jar в C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib\

Плюсю закинул его в C:\Program Files\Java\jre7\lib\ext\

Прописал эти пути в path

а также создал переменную CLASSPATH 

И в ней тоже указал эти пути. 

Все равно таже ошибка

ImportError: No module named oracle.jdbc.driver.OracleDriver

Версия java:
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
 
Как подключиться через cx_Oracle я не понял. 
Нужно сначала выполнить Import Library cx_Oracle? 

(D.Z.) #7

Тоже не знал, что есть уже отдельная библиотека для Oracle, поэтому написал свою. Спасибо, утащил оттуда некоторые keyword.

Кстати, может быть, кому-то будет интересно: keyword, позволяющий передавать в Robot Framework dbms_output

```python def execute_plsql_block_with_dbms_output (self,plsqlStatement): """ Выполнение PL\SQL блока с dbms_output()
    *Example:*\n
    | *Settings* | *Value* |
    | Library    |       OracleDB |
   
    | *Variables* | *Value* |
    | ${var}    |       4 |
   
    | *Test Cases* | *Action* | *Argument* | *Argument* | *Argument* |
    | Simple |
    |    | ${statement}=  |  catenate   |   SEPARATOR=\r\n  |    DECLARE  |
    |    | ...            |             |                     |       a NUMBER := ${var}; |
    |    | ...            |              |                     |   BEGIN |
    |    | ...            |              |                    |       a := a + 1; |
    |    | ...            |              |                    |        if a = 4 then |
    |    | ...            |              |                    |         raise_application_error ( -20001, 'This is a custom error' ); |
    |    | ...            |              |                    |        end if; |
    |    | ...            |              |                    |        dbms_output.put_line ('text '||a||', e-mail text'); |
    |    | ...            |              |                    |        dbms_output.put_line ('string 2 '); |
    |    | ...            |              |                    |     END; |
    |    | @{dbms}=       | Execute Plsql Bblock With Dbms Output   |  ${statement} |
    =&gt;\n
    | @{dbms}| text 5, e-mail text |
    | | string 2 |
    """
    cursor = None
    dbms_output = []
    try:
        cursor = self._connection.cursor()
        cursor.callproc("dbms_output.enable")
        self._execute_sql (cursor,plsqlStatement)
        statusVar = cursor.var(cx_Oracle.NUMBER)
        lineVar = cursor.var(cx_Oracle.STRING)
        while True:
            cursor.callproc("dbms_output.get_line", (lineVar, statusVar))
            if statusVar.getvalue() != 0:
                break
            dbms_output.append(lineVar.getvalue())
        return dbms_output
    finally:
        if cursor:
            self._connection.rollback()

(D.Z.) #8
Как подключиться через cx_Oracle я не понял. 
Нужно сначала выполнить Import Library cx_Oracle? 

 

Проверьте, что у Вас установлен Oracle Client и соответствующая ему версия cx_Oracle.


(rmerkushin) #9

У меня ставится без проблем:

C:\OracleLibrary>python setup.py install
running install
running build
running build_py
creating build
creating build\lib
creating build\lib\OracleLibrary
copying src\OracleLibrary\assertion.py -> build\lib\OracleLibrary
copying src\OracleLibrary\connection_manager.py -> build\lib\OracleLibrary
copying src\OracleLibrary\query.py -> build\lib\OracleLibrary
copying src\OracleLibrary\__init__.py -> build\lib\OracleLibrary
running install_lib
running install_egg_info
Removing C:\Python27\Lib\site-packages\robotframework_oraclelibrary-0.1-py2.7.egg-info
Writing C:\Python27\Lib\site-packages\robotframework_oraclelibrary-0.1-py2.7.egg-info
Если неставится так, достаточно скопировать из папки src папку OracleLibrary в C:\Python27\Lib\site-packages (ну или куда он там у вас установлен)
Так же должен быть установлен Oracle Client x86 причем Runtime а не просто Instant Client (с x64 у меня не получалось сработаться), для удобства лучше найти отдельный iso образ, на сайте Oracle я не нашел где его скачать, по этому брал с торрентов :)
Потом нужна библиотека cx_Oracle, взять тут: https://pypi.python.org/pypi/cx_Oracle
 
Когда все библиотеки\клиенты будут установлены, подключаться так:
| Connect To Database By Connection String | user1/qwerty@localhost:1521/db_serv1 | Russian.AL32UTF8 |
Все остальные нюансы описаны в документации.

(Mykhailo Poliarush) #10

ну такие библиотеки могут появляться как грибы после дождя

это просто адаптированная библиотека DatabaseLibrary c изменениями под Oracle, не более того=


(rmerkushin) #11

Пишешь кейворд, например Connect To Database Using Custom Params и первым параметром передаешь ему cx_Oracle, выше я писал пример.


(rmerkushin) #12

Так и есть, писал сам. DatabaseLibrary не давала мне возможности исполнять pl/sql скрипты, т.к. там каждая строка выполняется отдельно. Для выполнения pl/sql нужно группировать скрипт методом prepare который есть в cx_Oracle, но он не поддерживается PyDBAPI 2.0.

Есть правда один нюанс, у меня не получилось выполнить скрипт более чем с одним блоком begin\end, что в приницпе не так страшно. Если у кого есть идеи как это поправить напишите, буду признателен :)

з.ы.: Вставка между блоками "/" не решает проблему и дает ошибку оракла:

DatabaseError: ORA-06550: line 20, column 1:
PLS-00103: Encountered the symbol "/" The symbol "/" was ignored.
 
 а без него оракл точно так же жалуется на begin :-D

(kom) #13

Спасибо, не заметил что есть такой кейворд.

Только подключаться нужно не так, а именно в такой последовательности: 

DatabaseLibrary.Connect To Database Using Custom Params cx_Oracle 'USER/password@database_host:port/SID'

 


(kom) #14

Скажите пожалуйста, как добавить этот кейворд, я скопировал этот код в query.py в конце, теперь при импорте DatabaseLibrary в питоне библиотека импортируется и кейворд доступен:

DatabaseLibrary.Query.execute_with_dbms_output

Но в ride этого кейворда в DatabaseLibrary не видно, как и раньше.


(Dmitriy Zverev) #15

Данная библиотека теперь доступна тут

Подключается, как обычная библиотека robot framework

Документация