Search
Write a publication
Pull to refresh

Доступ к BLOB-полям БД Oracle из Python

Недавно у меня появилась задача со следующими исходными данными:
  • Необходимо выгрузить на диск данные из blob-полей таблицы;
  • СУБД Oracle установлена на отдельном сервере;
  • Данные должны выгружаться на локальную машину с операционной системой Ubuntu 9.10.

Решено было написать скрипт на любимом языке — Python. Но так как Python, по умолчанию, не умеет работать с Oracle, нужно его этому обучить.

Установка библиотек и подготовка к работе


Для работы с Oracle потребуются следующие библиотеки cx_Oracle и Oracle Instant Client. Но так как ни той ни другой библиотеки в виде deb-пакета я не нашел, пришлось делать их самому.

Шаг 1. Сначала устанавливаем пакет alien, который умеет преобразовывать rpm-пакеты в deb:

sudo apt-get install alien

Шаг 2. Идем на сайт cx_Oracle и скачиваем версию, подходящую Вам:

У меня Python 2.6 (для проверки версии выполнить нужно команду python -V) и Oracle 11 версии, поэтому я выбрал версию CentOS 5 i386 RPM (Oracle 11g, UNICODE, Python 2.6)

Шаг 3. На сайте Oracle скачиваем Oracle Instant Client:

Шаг 4. Устанавливаем rpm-пакеты с помощью alien:

sudo alien -i cx_Oracle-5.0.3-11g-unicode-py26-1.i386.rpm

sudo alien -i oracle-instantclient11.2-basic-11.2.0.1.0-1.i386.rpm


Шаг 5. Прописываем пути до библиотек:

export ORACLE_HOME=/usr/lib/oracle/11.2/client

export LD_LIBRARY_PATH=$ORACLE_HOME/lib

export PATH=$PATH:$ORACLE_HOME/bin


Шаг 6. Прописываем адрес сервера БД в файле tnsnames.ora. Обычно этот файл находится в директории $ORACLE_HOME/network/admin.

Создаем файл tnsnames.ora в директории $ORACLE_HOME/network/admin:

mkdir $ORACLE_HOME/network

mkdir $ORACLE_HOME/network/admin

touch $ORACLE_HOME/network/admin/tnsnames.ora


И записываем туда следующий код:

название_соединения =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = адрес_сервера)(PORT = порт))
)
(CONNECT_DATA =
(SERVICE_NAME = имя_инстанса)
)
)


Шаг 6. Устанавливаем библиотеку libaio1, которая требуется клиенту Oracle:

sudo apt-get install libaio1

Шаг 7. Пробуем подключиться к Oracle

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

export NLS_LANG=RUSSIAN_CIS.AL32UTF8

Подключаемся:

sqlplus <user_name>@<название соединения>

Если появилось приветствие Oracle, то все настроено верно.

Шаг 8. Создаем тестовую таблицу

CREATE TABLE TestTable (id NUMBER, blobfield BLOB);

На этом подготовка завершена.

Пишем скрипт


Я приведу текст простейшего скрипта, который загружает данные в таблицу и выгружает их на диск.

Copy Source | Copy HTML
  1. # -*- coding: utf-8 -*-
  2.  
  3. import cx_Oracle
  4.  
  5. # Создаем массив файлов, которые будут загружены в БД. 
  6. # Я кинул файлы в директорию со скриптом, чтобы не прописывать абсолютные пути
  7. inputs = []
  8. inputs.append(open('DSC_0035.jpg', 'rb'))
  9. inputs.append(open('DSC_0036.jpg', 'rb'))
  10.  
  11. # Подключаемся к БД
  12. dbconn = cx_Oracle.connect('user', 'password', 'host_name/service_name')
  13. dbconn.autocommit = True
  14.  
  15. cur = dbconn.cursor()
  16. cur.setinputsizes(blobfield=cx_Oracle.BLOB)
  17.  
  18. # Записываем данные в БД
  19. i = 1
  20. for input in inputs:
  21.     file = input.read()
  22.     cur.execute("INSERT INTO TestTable (id, blobfield) VALUES(:id, :blobfield)", {'id':i, 'blobfield':file})
  23.     input.close()
  24.     i += 1
  25.  
  26. # Забираем данные
  27. cur.execute('select id, blobfield from TestTable')
  28.  
  29. results = cur.fetchall()
  30.  
  31. for id, blobfield in results:
  32.     output = open(str(id)+'.jpg', 'wb')
  33.     blob = blobfield.read()
  34.     output.write(blob)
  35.     output.close()
  36.  
  37. # Закрываем соединение
  38. dbconn.close()

После выполнения в директории скрипта должны появиться файлы (1.jpg и 2.jpg), являющиеся копиями файлов DSC_0035.jpg и DSC_0035.jpg.

Ну вот, собственно, и все =)
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.