Удаленное хранение данных становится все более распространенным. Все популярнее и востребованее становятся различные онлайн-библиотеки моделей, материалов, текстур и ассетов. Для хранения данных в таких библиотеках чаще всего используются базы данных. PostgreSQL – одна из наиболее продвинутых и функциональных свободных баз данных с открытым исходным кодом, с которой можно соединяться и работать через Blender Python API.
Подготовка Blender к работе с базой данных PostgreSQL
В базовом дистрибутиве Blender отсутствуют модули для подключения к базе данных PostgreSQL. Однако мы можем установить их при помощи пакетного менеджера pip.
Установим необходимые нам для работы пакеты модулей прямо в директорию установки Blender. Это нужно проделать только один раз, после чего мы в любом скрипте, аддоне или просто в текстовом редакторе Text Editor в Blender сможем получить к ним доступ при помощи стандартной команды импорта import.
Самым популярным модулем для взаимодействия с базой данных PostgreSQL является Psycopg.
Для того, чтобы установить этот модуль, запустим Blender с правами администратора (“Запуск от имени Администратора” в ОС Windows или с правами root в ОС Linux).
Откроем окно Text Editor и введем следующий код:
1 2 3 4 5 6 7 8 9 10 11 |
import subprocess import sys import os python_exe = os.path.join(sys.prefix, 'bin', 'python.exe') target = os.path.join(sys.prefix, 'lib', 'site-packages') subprocess.call([python_exe, '-m', 'ensurepip']) subprocess.call([python_exe, '-m', 'pip', 'install', '--upgrade', 'pip']) subprocess.call([python_exe, '-m', 'pip', 'install', '--upgrade', 'psycopg2-binary', '-t', target]) print('Psycopg2 installed') |
Нажатием на кнопку со стрелкой “Run Script” выполним его.
После завершения установки, мы сможем использовать установленный модуль, импортировав его:
1 |
import psycopg2 |
Работа с базой данных PostgreSQL через Blender Python API
Для подключения к базе данных в первую очередь нужно создать соединение с ней.
Для наладки соединения с базой нам понадобятся следующие данные:
- адрес хоста базы данных
- имя пользователя базы данных
- пароль для этого пользователя
- имя базы данных, к которой будет осуществляться подключение
Их можно получить у системного администратора, ответственного за установку базы данных на сервере.
Создадим соединение с базой данных:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import psycopg2 db_host = '_HOST_' db_name = '_DATABASE_' db_user = '_USER_' db_password = '_PASSWORKD_' con = psycopg2.connect( database=db_name, user=db_user, password=db_password, host=db_host ) print(con) # <connection object at 0x000001FA94C34... |
Весь обмен данными с базой PostgreSQL ведется через специальный объект соединения cursor.
Для начала создадим в базе данных таблицу с именем blender_objects и двумя полями – name и location, в которые в дальнейшем сможем помещать имена и координаты местоположения объектов в сцене.
1 2 3 4 5 6 7 8 |
with con: with con.cursor() as cursor: cursor.execute('CREATE TABLE IF NOT EXISTS blender_objects (' 'id SERIAL PRIMARY KEY,' 'name VARCHAR(128) NOT NULL,' 'location VARCHAR(128) NOT NULL' ');' ) |
Обратите внимание на то, что мы два раза использовали конструкцию with.
C соединением:
1 |
with con: |
Это нужно для того, чтобы транзакция автоматически закоммитилась. Автокоммит в этом случае вызывается сразу после завершения блока кода внутри with.
Соединение при этом не закрывается и остается открытым для дальнейшего использования.
С объектом cursor:
1 |
with con.cursor() as cursor: |
Это нужно, чтобы курсор автоматически закрылся по завершении выполнения кода внутри блока with.
Создав таблицу, мы можем заполнять ее данными.
Занесем в таблицу имя и координаты текущего активного объекта в сцене (если сцена пустая – предварительно добавим в нее любой меш, например, куб: shift + a – Mesh – Cube)
1 2 3 4 5 6 7 8 9 |
with con: with con.cursor() as cursor: cursor.execute('INSERT INTO blender_objects (name, location)' 'VALUES(%(name)s, %(location)s);', { 'name': bpy.context.object.name, 'location': bpy.context.object.location[:] } ) |
В инструкции INSERT мы использовали два именованных параметра %(name)s и %(location)s), значения которым задали в словаре, следующем за самой инструкцией. Имена ключей словаря name и location должны соответствовать именам параметров в инструкции INSERT.
Открыв таблицу, мы можем убедиться, что данные в нее успешно занесены.
Теперь мы можем получить данные из таблицы обратно в Blender:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
with con: with con.cursor() as cursor: cursor.execute('SELECT name, location FROM blender_objects ' 'WHERE name = %(name)s;', { 'name': bpy.context.object.name } ) rows = cursor.fetchall() print(rows) bpy.context.object.location = eval(rows[0][1]) # [('Cube', '(1.4741322994232178,1.6460041999816895,0.0)')] |
Мы получили данные из базы и занесли результат выполнения запроса в переменную rows.
Теперь мы можем установить координаты для текущего активного объекта равные координатам, полученным из базы.
После завершения работы с базой данных соединение нужно закрыть:
1 |
con.close() |