Usare Ruby per connettersi ed eseguire comandi SQL in Azure Cosmos DB for PostgreSQL
SI APPLICA A: Azure Cosmos DB for PostgreSQL (con tecnologia basata su estensione di database Citus per PostgreSQL)
Questa guida di avvio rapido illustra come usare il codice Ruby per connettersi a un cluster e usare istruzioni SQL per creare una tabella. Si inseriranno dati su cui eseguire query per poi aggiornarli ed eliminarli nel database. I passaggi descritti in questo articolo presuppongono che si abbia familiarità con lo sviluppo Ruby e non si abbia familiarità con Azure Cosmos DB for PostgreSQL.
Installare la libreria PostgreSQL
Gli esempi di codice in questo articolo richiedono pg gem. È necessario installare pg con gestione pacchetti di linguaggio, come bundler.
Connettersi, creare una tabella e inserire dati
Usare il codice seguente per connettersi e creare una tabella usando l'istruzione SQL CREATE TABLE, quindi aggiungere righe alla tabella usando l'istruzione SQL INSERT INTO. Il codice usa un oggetto PG::Connection
con il costruttore per la connessione ad Azure Cosmos DB for PostgreSQL. Chiama quindi il metodo exec()
per eseguire i comandi DROP, CREATE TABLE e INSERT INTO. Il codice cerca gli errori usando la classe PG::Error
. Chiama infine il metodo close()
per chiudere la connessione prima di terminare.
Nel codice sostituire <il cluster> con il nome e <la password> del cluster con la password dell'amministratore o il token ID 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
Distribuire le tabelle
Azure Cosmos DB for PostgreSQL offre la super potenza di distribuzione delle tabelle tra più nodi per la scalabilità. Il comando seguente consente di distribuire una tabella. Per altre informazioni su create_distributed_table
e sulla colonna di distribuzione, vedere qui.
Nota
La distribuzione delle tabelle consente di aumentare le dimensioni in tutti i nodi di lavoro aggiunti al cluster.
Usare il codice seguente per connettersi al database e distribuire la tabella. Nel codice sostituire <cluster> con il nome del cluster e <password> con la password amministratore.
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
Leggere i dati
Usare il codice seguente per connettersi e leggere i dati usando un'istruzione SQL SELECT.
Il codice chiama il metodo exec()
per eseguire il comando SELECT, mantenendo i risultati in un set di risultati. Viene eseguita l'iterazione della raccolta di set di risultati usando il ciclo do resultSet.each
, mantenendo i valori della riga corrente nella variabile di riga. Nel codice sostituire <cluster> con il nome del cluster e <password> con la password amministratore.
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
Aggiornamento dei dati
Usare il codice seguente per connettersi e aggiornare i dati usando un'istruzione SQL UPDATE. Nel codice sostituire <cluster> con il nome del cluster e <password> con la password amministratore.
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
Eliminare dati
Usare il codice seguente per connettersi ed eliminare i dati usando un'istruzione SQL DELETE. Nel codice sostituire <cluster> con il nome del cluster e <password> con la password amministratore.
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
Comando COPY per un inserimento dati rapido
Il comando COPY può produrre una velocità effettiva elevata durante l'inserimento di dati in Azure Cosmos DB for PostgreSQL. Il comando COPY può inserire dati in file o da micro batch di dati in memoria per l'inserimento in tempo reale.
Comando COPY per caricare dati da un file
Il codice seguente copia i dati da un file CSV a una tabella del database. Richiede il file pharmacies.csv. Nel codice sostituire <cluster> con il nome del cluster e <password> con la password amministratore.
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
Comando COPY per caricare i dati in memoria
Il codice seguente copia i dati in memoria in una tabella. Nel codice sostituire <cluster> con il nome del cluster e <password> con la password amministratore.
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
Retry dell'app per gli errori delle richieste di database
A volte è possibile che le richieste di database eseguite dall'applicazione non riescano. Tali problemi possono verificarsi in scenari diversi, ad esempio errori di rete tra app e database, password non corretta e così via. Alcuni problemi possono essere temporanei e risolversi in pochi secondi o pochi minuti. È possibile configurare la logica di retry nell'app per risolvere gli errori temporanei.
La configurazione della logica di retry nell'app consente di migliorare l'esperienza dell'utente finale. In scenari di errore gli utenti attenderanno semplicemente un po' più a lungo per consentire all'applicazione di gestire le richieste, anziché riscontrare errori.
L'esempio seguente illustra come implementare la logica di retry nell'app. Il frammento di codice di esempio tenta una richiesta di database ogni 60 secondi (fino a cinque volte) fino a quando non riesce. Il numero e la frequenza dei tentativi possono essere configurati in base alle esigenze dell'applicazione.
Nel codice sostituire <cluster> con il nome del cluster e <password> con la password amministratore.
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
Passaggi successivi
- Vedere come l'API di Azure Cosmos DB for PostgreSQL estende PostgreSQL e provare utili query di diagnostica
- Scegliere le dimensioni del cluster migliori per il carico di lavoro
- Monitorare le prestazioni del cluster