Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
QLDBAmazon-Treiber für Python — Kochbuch-Referenz
Wichtig
Hinweis zum Ende des Supports: Bestandskunden können Amazon QLDB bis zum Ende des Supports am 31.07.2025 nutzen. Weitere Informationen finden Sie unter Migrieren eines Amazon QLDB Ledgers zu Amazon Aurora SQL Postgre
Dieses Referenzhandbuch zeigt allgemeine Anwendungsfälle des QLDB Amazon-Treibers für Python. Es enthält Python-Codebeispiele, die zeigen, wie der Treiber verwendet wird, um grundlegende Create-, Lese-, Update- und Delete (CRUD) -Operationen auszuführen. Es enthält auch Codebeispiele für die Verarbeitung von Amazon Ion-Daten. Darüber hinaus werden in diesem Leitfaden bewährte Verfahren zur idempotenten Gestaltung von Transaktionen und zur Implementierung von Eindeutigkeitsbeschränkungen beschrieben.
Anmerkung
Gegebenenfalls haben einige Anwendungsfälle unterschiedliche Codebeispiele für jede unterstützte Hauptversion des QLDB Python-Treibers.
Inhalt
- Der Treiber wird importiert
- Der Treiber wird instanziiert
- CRUDOperationen
- Arbeiten mit Amazon Ion
Der Treiber wird importiert
Das folgende Codebeispiel importiert den Treiber.
Anmerkung
In diesem Beispiel wird auch das Amazon Ion-Paket (amazon.ion.simpleion
) importiert. Sie benötigen dieses Paket, um Ion-Daten zu verarbeiten, wenn Sie einige Datenoperationen in dieser Referenz ausführen. Weitere Informationen hierzu finden Sie unter Arbeiten mit Amazon Ion.
Der Treiber wird instanziiert
Im folgenden Codebeispiel wird eine Instanz des Treibers erstellt, die mithilfe der Standardeinstellungen eine Verbindung zu einem angegebenen Ledger-Namen herstellt.
CRUDOperationen
QLDBführt die Operationen create, read, update und delete (CRUD) als Teil einer Transaktion aus.
Warnung
Als bewährte Methode sollten Sie Ihre Schreibtransaktionen strikt idempotent gestalten.
Machen Sie Transaktionen idempotent
Wir empfehlen, Schreibtransaktionen idempotent zu machen, um unerwartete Nebenwirkungen bei Wiederholungsversuchen zu vermeiden. Eine Transaktion ist idempotent, wenn sie mehrfach ausgeführt werden kann und jedes Mal identische Ergebnisse liefert.
Stellen Sie sich zum Beispiel eine Transaktion vor, die ein Dokument in eine Tabelle mit dem Namen einfügt. Person
Bei der Transaktion sollte zunächst geprüft werden, ob das Dokument bereits in der Tabelle vorhanden ist. Ohne diese Prüfung könnte die Tabelle am Ende doppelte Dokumente enthalten.
Nehmen wir an, die Transaktion wird serverseitig QLDB erfolgreich festgeschrieben, aber der Client läuft ab, während er auf eine Antwort wartet. Wenn die Transaktion nicht idempotent ist, könnte dasselbe Dokument bei einem erneuten Versuch mehrmals eingefügt werden.
Verwendung von Indizes, um vollständige Tabellenscans zu vermeiden
Es wird außerdem empfohlen, Anweisungen mit einer WHERE
Prädikatklausel unter Verwendung eines Gleichheitsoperators für ein indiziertes Feld oder eine Dokument-ID auszuführen, z. B. oder. WHERE indexedField = 123
WHERE indexedField IN (456, 789)
Ohne diese indizierte Suche QLDB muss ein Tabellenscan durchgeführt werden, was zu Transaktions-Timeouts oder Konflikten mit optimistischer Parallelitätssteuerung () führen kann. OCC
Mehr über OCC erfahren Sie unter QLDBAmazon-Parallelitätsmodell.
Implizit erstellte Transaktionen
Die Methode pyqldb.driver.qldb_driver.execute_lambda akzeptiert eine Lambda-Funktion, die eine Instanz von pyqldb.execution.executor.ExecutorExecutor
implizit erstellte Transaktion.
Sie können Anweisungen innerhalb der Lambda-Funktion ausführen, indem Sie die Methode execute_statement des Transaktionsausführers
Anmerkung
Die execute_statement
Methode unterstützt sowohl Amazon Ion-Typen als auch native Python-Typen. Wenn Sie einen nativen Python-Typ als Argument an übergebenexecute_statement
, konvertiert der Treiber ihn mithilfe des amazon.ion.simpleion
Moduls in einen Ion-Typ (vorausgesetzt, dass die Konvertierung für den angegebenen Python-Datentyp unterstützt wird). Die unterstützten Datentypen und Konvertierungsregeln finden Sie im simpleion-Quellcode
In den folgenden Abschnitten wird gezeigt, wie grundlegende CRUD Operationen ausgeführt, eine benutzerdefinierte Wiederholungslogik angegeben und Eindeutigkeitsbeschränkungen implementiert werden.
Inhalt
Erstellen von Tabellen
def create_table(transaction_executor): transaction_executor.execute_statement("CREATE TABLE Person") qldb_driver.execute_lambda(lambda executor: create_table(executor))
Erstellen von Indizes
def create_index(transaction_executor): transaction_executor.execute_statement("CREATE INDEX ON Person(GovId)") qldb_driver.execute_lambda(lambda executor: create_index(executor))
Dokumente lesen
# Assumes that Person table has documents as follows: # { "GovId": "TOYENC486FH", "FirstName": "Brent" } def read_documents(transaction_executor): cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = 'TOYENC486FH'") for doc in cursor: print(doc["GovId"]) # prints TOYENC486FH print(doc["FirstName"]) # prints Brent qldb_driver.execute_lambda(lambda executor: read_documents(executor))
Verwenden von Abfrageparametern
Im folgenden Codebeispiel wird ein systemeigener Abfrageparameter verwendet.
cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = ?", 'TOYENC486FH')
Das folgende Codebeispiel verwendet einen Abfrageparameter vom Typ Ion.
name = ion.loads('Brent') cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE FirstName = ?", name)
Das folgende Codebeispiel verwendet mehrere Abfrageparameter.
cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = ? AND FirstName = ?", 'TOYENC486FH', "Brent")
Das folgende Codebeispiel verwendet eine Liste von Abfrageparametern.
gov_ids = ['TOYENC486FH','ROEE1','YH844'] cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId IN (?,?,?)", *gov_ids)
Anmerkung
Wenn Sie eine Abfrage ohne indizierte Suche ausführen, wird ein vollständiger Tabellenscan aufgerufen. In diesem Beispiel empfehlen wir, einen Index für das GovId
Feld zu verwenden, um die Leistung zu optimieren. Ohne aktivierten GovId
Index können Abfragen eine höhere Latenz haben und auch zu OCC Konfliktausnahmen oder Transaktions-Timeouts führen.
Dokumente werden eingefügt
Im folgenden Codebeispiel werden systemeigene Datentypen eingefügt.
def insert_documents(transaction_executor, arg_1): # Check if doc with GovId:TOYENC486FH exists # This is critical to make this transaction idempotent cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = ?", 'TOYENC486FH') # Check if there is any record in the cursor first_record = next(cursor, None) if first_record: # Record already exists, no need to insert pass else: transaction_executor.execute_statement("INSERT INTO Person ?", arg_1) doc_1 = { 'FirstName': "Brent", 'GovId': 'TOYENC486FH', } qldb_driver.execute_lambda(lambda executor: insert_documents(executor, doc_1))
Im folgenden Codebeispiel werden Ion-Datentypen eingefügt.
def insert_documents(transaction_executor, arg_1): # Check if doc with GovId:TOYENC486FH exists # This is critical to make this transaction idempotent cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = ?", 'TOYENC486FH') # Check if there is any record in the cursor first_record = next(cursor, None) if first_record: # Record already exists, no need to insert pass else: transaction_executor.execute_statement("INSERT INTO Person ?", arg_1) doc_1 = { 'FirstName': 'Brent', 'GovId': 'TOYENC486FH', } # create a sample Ion doc ion_doc_1 = simpleion.loads(simpleion.dumps(doc_1))) qldb_driver.execute_lambda(lambda executor: insert_documents(executor, ion_doc_1))
Diese Transaktion fügt ein Dokument in die Person
Tabelle ein. Vor dem Einfügen wird zunächst geprüft, ob das Dokument bereits in der Tabelle vorhanden ist. Diese Prüfung macht die Transaktion ihrem Wesen nach idempotent. Selbst wenn Sie diese Transaktion mehrmals ausführen, hat sie keine unbeabsichtigten Nebenwirkungen.
Anmerkung
In diesem Beispiel empfehlen wir, einen Index für das GovId
Feld zu verwenden, um die Leistung zu optimieren. Wenn ein Index nicht aktiviert istGovId
, können Anweisungen eine längere Latenz haben und auch zu OCC Konfliktausnahmen oder Transaktions-Timeouts führen.
Einfügen mehrerer Dokumente in eine Anweisung
Um mehrere Dokumente mit einer einzigen INSERT Anweisung einzufügen, können Sie der Anweisung wie folgt einen Parameter vom Typ list übergeben.
# people is a list transaction_executor.execute_statement("INSERT INTO Person ?", people)
Bei der Übergabe einer Liste setzen Sie den Platzhalter für die Variable (?
) nicht in doppelte spitze Klammern (<<...>>
). In manuellen PartiQL-Anweisungen bezeichnen doppelte spitze Klammern eine ungeordnete Sammlung, die als Tasche bezeichnet wird.
Dokumente werden aktualisiert
Im folgenden Codebeispiel werden systemeigene Datentypen verwendet.
def update_documents(transaction_executor, gov_id, name): transaction_executor.execute_statement("UPDATE Person SET FirstName = ? WHERE GovId = ?", name, gov_id) gov_id = 'TOYENC486FH' name = 'John' qldb_driver.execute_lambda(lambda executor: update_documents(executor, gov_id, name))
Das folgende Codebeispiel verwendet Ion-Datentypen.
def update_documents(transaction_executor, gov_id, name): transaction_executor.execute_statement("UPDATE Person SET FirstName = ? WHERE GovId = ?", name, gov_id) # Ion datatypes gov_id = simpleion.loads('TOYENC486FH') name = simpleion.loads('John') qldb_driver.execute_lambda(lambda executor: update_documents(executor, gov_id, name))
Anmerkung
In diesem Beispiel empfehlen wir, einen Index für das GovId
Feld zu verwenden, um die Leistung zu optimieren. Wenn ein Index nicht aktiviert istGovId
, können Anweisungen eine längere Latenz haben und auch zu OCC Konfliktausnahmen oder Transaktions-Timeouts führen.
Dokumente löschen
Im folgenden Codebeispiel werden systemeigene Datentypen verwendet.
def delete_documents(transaction_executor, gov_id): cursor = transaction_executor.execute_statement("DELETE FROM Person WHERE GovId = ?", gov_id) gov_id = 'TOYENC486FH' qldb_driver.execute_lambda(lambda executor: delete_documents(executor, gov_id))
Das folgende Codebeispiel verwendet Ion-Datentypen.
def delete_documents(transaction_executor, gov_id): cursor = transaction_executor.execute_statement("DELETE FROM Person WHERE GovId = ?", gov_id) # Ion datatypes gov_id = simpleion.loads('TOYENC486FH') qldb_driver.execute_lambda(lambda executor: delete_documents(executor, gov_id))
Anmerkung
In diesem Beispiel empfehlen wir, einen Index für das GovId
Feld zu verwenden, um die Leistung zu optimieren. Wenn ein Index nicht aktiviert istGovId
, können Anweisungen eine längere Latenz haben und auch zu OCC Konfliktausnahmen oder Transaktions-Timeouts führen.
Ausführung mehrerer Anweisungen in einer Transaktion
# This code snippet is intentionally trivial. In reality you wouldn't do this because you'd # set your UPDATE to filter on vin and insured, and check if you updated something or not. def do_insure_car(transaction_executor, vin): cursor = transaction_executor.execute_statement( "SELECT insured FROM Vehicles WHERE vin = ? AND insured = FALSE", vin) first_record = next(cursor, None) if first_record: transaction_executor.execute_statement( "UPDATE Vehicles SET insured = TRUE WHERE vin = ?", vin) return True else: return False def insure_car(qldb_driver, vin_to_insure): return qldb_driver.execute_lambda( lambda executor: do_insure_car(executor, vin_to_insure))
Logik für Wiederholversuche
Die execute_lambda
Treibermethode verfügt über einen integrierten Wiederholungsmechanismus, der die Transaktion wiederholt, wenn eine Ausnahme auftritt, die wiederholt werden kann (z. B. Timeouts oder Konflikte). OCC
Implementierung von Eindeutigkeitsbeschränkungen
QLDBunterstützt keine eindeutigen Indizes, aber Sie können dieses Verhalten in Ihrer Anwendung implementieren.
Angenommen, Sie möchten eine Eindeutigkeitsbeschränkung für das GovId
Feld in der Person
Tabelle implementieren. Zu diesem Zweck können Sie eine Transaktion schreiben, die Folgendes tut:
-
Bestätigen Sie, dass die Tabelle keine vorhandenen Dokumente mit einem angegebenen Wert enthält
GovId
. -
Fügt das Dokument ein, wenn die Assertion erfolgreich ist.
Wenn eine konkurrierende Transaktion gleichzeitig die Assertion besteht, wird nur eine der Transaktionen erfolgreich festgeschrieben. Die andere Transaktion schlägt mit einer OCC Konfliktausnahme fehl.
Das folgende Codebeispiel zeigt, wie diese Eindeutigkeitsbeschränkungslogik implementiert wird.
def insert_documents(transaction_executor, gov_id, document): # Check if doc with GovId = gov_id exists cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = ?", gov_id) # Check if there is any record in the cursor first_record = next(cursor, None) if first_record: # Record already exists, no need to insert pass else: transaction_executor.execute_statement("INSERT INTO Person ?", document) qldb_driver.execute_lambda(lambda executor: insert_documents(executor, gov_id, document))
Anmerkung
In diesem Beispiel empfehlen wir, einen Index für das GovId
Feld zu verwenden, um die Leistung zu optimieren. Wenn ein Index nicht aktiviert istGovId
, können Anweisungen eine längere Latenz haben und auch zu OCC Konfliktausnahmen oder Transaktions-Timeouts führen.
Arbeiten mit Amazon Ion
In den folgenden Abschnitten wird gezeigt, wie das Amazon Ion-Modul zur Verarbeitung von Ion-Daten verwendet wird.
Inhalt
Das Ion-Modul importieren
import amazon.ion.simpleion as simpleion
Ion-Typen erstellen
Im folgenden Codebeispiel wird ein Ion-Objekt aus Ion-Text erstellt.
ion_text = '{GovId: "TOYENC486FH", FirstName: "Brent"}' ion_obj = simpleion.loads(ion_text) print(ion_obj['GovId']) # prints TOYENC486FH print(ion_obj['Name']) # prints Brent
Das folgende Codebeispiel erstellt ein Ion-Objekt aus einem Pythondict
.
a_dict = { 'GovId': 'TOYENC486FH', 'FirstName': "Brent" } ion_obj = simpleion.loads(simpleion.dumps(a_dict)) print(ion_obj['GovId']) # prints TOYENC486FH print(ion_obj['FirstName']) # prints Brent
Einen Ion-Binär-Dump abrufen
# ion_obj is an Ion struct print(simpleion.dumps(ion_obj)) # b'\xe0\x01\x00\xea\xee\x97\x81\x83\xde\x93\x87\xbe\x90\x85GovId\x89FirstName\xde\x94\x8a\x8bTOYENC486FH\x8b\x85Brent'
Einen Ion-Textdump abrufen
# ion_obj is an Ion struct print(simpleion.dumps(ion_obj, binary=False)) # prints $ion_1_0 {GovId:'TOYENC486FH',FirstName:"Brent"}
Weitere Informationen zur Arbeit mit Ion finden Sie in der Amazon Ion-Dokumentation