Использование Ruby для подключения и выполнения команд SQL в Azure Cosmos DB для PostgreSQL
Область применения: Azure Cosmos DB для PostgreSQL (на базе расширения базы данных Citus до PostgreSQL)
В этом кратком руководстве показано, как использовать код Ruby для подключения к кластеру и использовать инструкции SQL для создания таблицы. Затем вы вставляете, запрашиваете, обновляете и удаляете данные в базе данных. В этой статье предполагается, что вы знакомы с разработкой Ruby и не знакомы с Azure Cosmos DB для PostgreSQL.
Установка библиотеки PostgreSQL
В примерах кода в этой статье требуется драгоценный камень pg . Вам потребуется установить pg с помощью диспетчера языковых пакетов (например, пакета).
Подключение, создание таблицы и вставка данных
Используйте следующий код для подключения и создания таблицы с помощью инструкции CREATE TABLE SQL, а затем добавьте строки в таблицу с помощью инструкции INSERT INTO SQL. Код использует объект с конструктором PG::Connection
для подключения к Azure Cosmos DB для PostgreSQL. Затем вызывает метод для выполнения команд exec()
DROP, CREATE TABLE и INSERT INTO. Код проверяет наличие ошибок с помощью PG::Error
класса. Затем вызывает метод close()
, чтобы закрыть соединение перед завершением.
В коде замените <кластер> именем кластера и <паролем паролем> администратора или маркером идентификатора Microsoft Entra.
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
Обновление данных
Используйте следующий код для подключения и обновления данных с помощью инструкции UPDATE SQL. В коде замените <кластер> именем кластера и <паролем паролем> администратора.
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 и попробуйте полезные диагностические запросы
- Выбор оптимального размера кластера для рабочей нагрузки
- Мониторинг производительности кластера