Использование Ruby для подключения и выполнения команд SQL в Azure Cosmos DB для PostgreSQL
ПРИМЕНИМО К: Azure Cosmos DB для PostgreSQL (на базе расширения базы данных Citus для PostgreSQL)
В этом кратком руководстве показано, как использовать код Ruby для подключения к кластеру и использовать инструкции SQL для создания таблицы. Затем вы будете вставлять, запрашивать, обновлять и удалять данные в базе данных. В этой статье предполагается, что вы знакомы с разработкой на Ruby и не работали с Azure Cosmos DB для PostgreSQL.
Установка библиотеки PostgreSQL
Для примеров кода в этой статье требуется pg gem. Вам потребуется установить pg с помощью диспетчера языковых пакетов (например, bundler).
Подключение, создание таблицы и вставка данных
Используйте следующий код для подключения и создания таблицы с помощью инструкции SQL CREATE TABLE, а затем добавьте строки в таблицу с помощью инструкции SQL INSERT INTO. Код использует объект с конструктором PG::Connection
для подключения к Azure Cosmos DB для PostgreSQL. Затем он вызывает метод exec()
для выполнения команд DROP, CREATE TABLE и INSERT INTO. Этот код проверяет наличие ошибок с помощью класса PG::Error
. После этого вызывается метод close()
, чтобы разорвать подключение перед завершением работы.
В коде замените <кластер> именем кластера, а <пароль> — паролем администратора.
require 'pg'
begin
# NOTE: Replace <cluster> and <password> in the connection string.
connection = PG::Connection.new("host=c-<cluster>.<uniqueID>.postgres.cosmos.azure.com port=5432 dbname=citus user=citus password=<password> sslmode=require")
puts 'Successfully created connection to database'
# Drop previous table of same name if one exists
connection.exec('DROP TABLE IF EXISTS pharmacy;')
puts 'Finished dropping table (if existed).'
# Drop previous table of same name if one exists.
connection.exec('CREATE TABLE pharmacy (pharmacy_id integer ,pharmacy_name text,city text,state text,zip_code integer);')
puts 'Finished creating table.'
# Insert some data into table.
connection.exec("INSERT INTO pharmacy (pharmacy_id,pharmacy_name,city,state,zip_code) VALUES (0,'Target','Sunnyvale','California',94001);")
connection.exec("INSERT INTO pharmacy (pharmacy_id,pharmacy_name,city,state,zip_code) VALUES (1,'CVS','San Francisco','California',94002);")
puts 'Inserted 2 rows of data.'
# Create index
connection.exec("CREATE INDEX idx_pharmacy_id ON pharmacy(pharmacy_id);")
rescue PG::Error => e
puts e.message
ensure
connection.close if connection
end
Распределение таблиц
Azure Cosmos DB для PostgreSQL предоставляет супер возможности распределения таблиц между несколькими узлами для обеспечения масштабируемости. С помощью приведенной ниже команды можно распределить таблицу. Дополнительные сведения о create_distributed_table
и столбце распределения см. здесь.
Примечание
Распределение таблиц позволяет увеличивать их по всем рабочим узлам, добавленным в кластер.
Используйте следующий код для подключения к базе данных и распространения таблицы: В коде замените <кластер> именем кластера, а <пароль> — паролем администратора.
require 'pg'
begin
# NOTE: Replace <cluster> and <password> in the connection string.
connection = PG::Connection.new("host=c-<cluster>.<uniqueID>.postgres.cosmos.azure.com port=5432 dbname=citus user=citus password=<password> sslmode=require")
puts 'Successfully created connection to database.'
# Super power of distributed tables.
connection.exec("select create_distributed_table('pharmacy','pharmacy_id');")
rescue PG::Error => e
puts e.message
ensure
connection.close if connection
end
Чтение данных
Используйте указанный ниже код с инструкцией SQL SELECT для подключения и чтения данных.
Код вызывает метод exec()
для выполнения команды SELECT, сохраняя результаты в результирующем наборе. Для коллекции набора результатов выполняется итерация с применением цикла do resultSet.each
. При этом данные строки текущего значения сохраняются в переменной строки. В коде замените <кластер> именем кластера, а <пароль> — паролем администратора.
require 'pg'
begin
# NOTE: Replace <cluster> and <password> in the connection string.
connection = PG::Connection.new("host=c-<cluster>.<uniqueID>.postgres.cosmos.azure.com port=5432 dbname=citus user=citus password=<password> sslmode=require")
puts 'Successfully created connection to database.'
resultSet = connection.exec('SELECT * from pharmacy')
resultSet.each do |row|
puts 'Data row = (%s, %s, %s, %s, %s)' % [row['pharmacy_id'], row['pharmacy_name'], row['city'], row['state'], row['zip_code ']]
end
rescue PG::Error => e
puts e.message
ensure
connection.close if connection
end
Обновление данных
Используйте следующий код для подключения и обновления данных с помощью инструкции SQL UPDATE. В коде замените <кластер> именем кластера, а <пароль> — паролем администратора.
require 'pg'
begin
# NOTE: Replace <cluster> and <password> in the connection string.
connection = PG::Connection.new("host=c-<cluster>.<uniqueID>.postgres.cosmos.azure.com port=5432 dbname=citus user=citus password=<password> sslmode=require")
puts 'Successfully created connection to database.'
# Modify some data in table.
connection.exec('UPDATE pharmacy SET city = %s WHERE pharmacy_id = %d;' % ['\'guntur\'',100])
puts 'Updated 1 row of data.'
rescue PG::Error => e
puts e.message
ensure
connection.close if connection
end
Удаление данных
Используйте указанный ниже код с инструкцией SQL DELETE для подключения и удаления данных. В коде замените <кластер> именем кластера, а <пароль> — паролем администратора.
require 'pg'
begin
# NOTE: Replace <cluster> and <password> in the connection string.
connection = PG::Connection.new("host=c-<cluster>.<uniqueID>.postgres.cosmos.azure.com port=5432 dbname=citus user=citus password=<password> sslmode=require")
puts 'Successfully created connection to database.'
# Delete some data in table.
connection.exec('DELETE FROM pharmacy WHERE city = %s;' % ['\'guntur\''])
puts 'Deleted 1 row of data.'
rescue PG::Error => e
puts e.message
ensure
connection.close if connection
end
Команда COPY для сверхбыстрого приема
Команда COPY может обеспечить огромную пропускную способность при приеме данных в Azure Cosmos DB для PostgreSQL. Команда COPY может принимать данные в файлах или из микропакетов данных в памяти для приема в реальном времени.
Команда COPY для загрузки данных из файла
Следующий код копирует данные из CSV-файла в таблицу базы данных. Для этого требуется файл pharmacies.csv. В коде замените <кластер> именем кластера, а <пароль> — паролем администратора.
require 'pg'
begin
filename = String('pharmacies.csv')
# NOTE: Replace <cluster> and <password> in the connection string.
connection = PG::Connection.new("host=c-<cluster>.<uniqueID>.postgres.cosmos.azure.com port=5432 dbname=citus user=citus password=<password> sslmode=require")
puts 'Successfully created connection to database.'
# Copy the data from Csv to table.
result = connection.copy_data "COPY pharmacy FROM STDIN with csv" do
File.open(filename , 'r').each do |line|
connection.put_copy_data line
end
puts 'Copied csv data successfully.'
end
rescue PG::Error => e
puts e.message
ensure
connection.close if connection
end
Команда COPY для загрузки данных в памяти
Следующий код копирует данные в памяти в таблицу. В коде замените <кластер> именем кластера, а <пароль> — паролем администратора.
require 'pg'
begin
# NOTE: Replace <cluster> and <password> in the connection string.
connection = PG::Connection.new("host=c-<cluster>.<uniqueID>.postgres.cosmos.azure.com port=5432 dbname=citus user=citus password=<password> sslmode=require")
puts 'Successfully created connection to database.'
enco = PG::TextEncoder::CopyRow.new
connection.copy_data "COPY pharmacy FROM STDIN", enco do
connection.put_copy_data [5000,'Target','Sunnyvale','California','94001']
connection.put_copy_data [5001, 'CVS','San Francisco','California','94002']
puts 'Copied in-memory data successfully.'
end
rescue PG::Error => e
puts e.message
ensure
connection.close if connection
end
Повторная попытка приложения при сбоях запросов к базе данных
Иногда запросы к базе данных из приложения могут завершаться ошибкой. Такие проблемы могут возникать при различных сценариях, включая сбой сети между приложением и базой данных, неправильный пароль и т. д. Некоторые проблемы могут быть временными и самостоятельно устраняться в течение нескольких секунд или минут. Для устранения временных ошибок можно настроить в приложении логику повторных попыток.
Настройка логики повторных попыток в приложении помогает улучшить взаимодействие с пользователем. В сценариях сбоя пользователи просто будут немного дольше ждать, пока приложение обслужит запросы, а не столкнутся с ошибками.
В приведенном ниже примере показано, как реализовать логику повторных попыток в вашем приложении. Фрагмент примера кода пытается выполнить запрос к базе данных каждые 60 секунд (до пяти раз) до достижения требуемого результата. Количество и частоту повторных попыток можно настроить в зависимости от требований вашего приложения.
В коде замените <кластер> именем кластера, а <пароль> — паролем администратора.
require 'pg'
def executeretry(sql,retryCount)
begin
for a in 1..retryCount do
begin
# NOTE: Replace <cluster> and <password> in the connection string.
connection = PG::Connection.new("host=c-<cluster>.<uniqueID>.postgres.cosmos.azure.com port=5432 dbname=citus user=citus password=<password> sslmode=require")
resultSet = connection.exec(sql)
return resultSet.each
rescue PG::Error => e
puts e.message
sleep 60
ensure
connection.close if connection
end
end
end
return nil
end
var = executeretry('select 1',5)
if var !=nil then
var.each do |row|
puts 'Data row = (%s)' % [row]
end
end
Дальнейшие действия
- Узнайте, как API Azure Cosmos DB для PostgreSQL расширяет Возможности PostgreSQL, и попробуйте использовать полезные диагностические запросы.
- Выбор оптимального размера кластера для рабочей нагрузки
- Мониторинг производительности кластера