Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Pemrograman Amazon DynamoDB dengan Python dan Boto3
Panduan ini memberikan orientasi kepada programmer yang ingin menggunakan Amazon DynamoDB dengan Python. Pelajari tentang berbagai lapisan abstraksi, manajemen konfigurasi, penanganan kesalahan, mengendalikan kebijakan coba ulang, mengelola keep-alive, dan banyak lagi.
Topik
Tentang Boto
Anda dapat mengakses DynamoDB dari Python dengan menggunakan AWS SDK resmi untuk Python, yang biasa disebut sebagai Boto3. Nama Boto (diucapkan boh-toh) berasal dari lumba-lumba air tawar asli Sungai Amazon. Perpustakaan Boto3 adalah versi utama ketiga perpustakaan, pertama kali dirilis pada tahun 2015. Pustaka Boto3 cukup besar, karena mendukung semua AWS layanan, bukan hanya DynamoDB. Orientasi ini hanya menargetkan bagian Boto3 yang relevan dengan DynamoDB.
Boto dikelola dan diterbitkan oleh AWS sebagai proyek sumber terbuka yang dihosting di. GitHub Ini dibagi menjadi dua paket: Boto core
-
Botocore menyediakan fungsionalitas tingkat rendah. Di Botocore Anda akan menemukan kelas klien, sesi, kredenSIAL, konfigurasi, dan pengecualian.
-
Boto3 dibangun di atas Botocore. Ini menawarkan antarmuka tingkat yang lebih tinggi dan lebih Pythonic. Secara khusus, ini mengekspos tabel DynamoDB sebagai Sumber Daya dan menawarkan antarmuka yang lebih sederhana dan lebih elegan dibandingkan dengan antarmuka klien berorientasi layanan tingkat rendah.
Karena proyek-proyek ini GitHub di-host, Anda dapat melihat kode sumber, melacak masalah terbuka, atau mengirimkan masalah Anda sendiri.
Menggunakan dokumentasi Boto
Mulai dengan dokumentasi Boto dengan sumber daya berikut:
-
Mulailah dengan bagian Quickstart
yang menyediakan titik awal yang solid untuk instalasi paket. Pergi ke sana untuk instruksi tentang menginstal Boto3 jika belum (Boto3 sering tersedia secara otomatis dalam AWS layanan seperti). AWS Lambda -
Setelah itu, fokus pada panduan DynamoDB dokumentasi.
Ini menunjukkan kepada Anda cara melakukan aktivitas DynamoDB dasar: membuat dan menghapus tabel, memanipulasi item, menjalankan operasi batch, menjalankan kueri, dan melakukan pemindaian. Contohnya menggunakan antarmuka sumber daya. Ketika Anda melihat itu menunjukkan boto3.resource('dynamodb')bahwa Anda menggunakan antarmuka sumber daya tingkat yang lebih tinggi. -
Setelah panduan, Anda dapat meninjau referensi DynamoDB.
Halaman arahan ini menyediakan daftar lengkap kelas dan metode yang tersedia untuk Anda. Di bagian atas, Anda akan melihat DynamoDB.Clientkelas. Ini menyediakan akses tingkat rendah ke semua operasi bidang kontrol dan bidang data. Di bagian bawah, lihatDynamoDB.ServiceResourcekelas. Ini adalah antarmuka Pythonic tingkat yang lebih tinggi. Dengan itu Anda dapat membuat tabel, melakukan operasi batch di seluruh tabel, atau mendapatkanDynamoDB.ServiceResource.Tableinstance untuk tindakan khusus tabel.
Memahami lapisan abstraksi klien dan sumber daya
Dua antarmuka yang akan Anda gunakan adalah antarmuka klien dan antarmuka sumber daya.
-
Antar muka klien tingkat rendah menyediakan pemetaan 1-ke-1 ke API layanan yang mendasarinya. Setiap API yang ditawarkan oleh DynamoDB tersedia melalui klien. Ini berarti antarmuka klien dapat menyediakan fungsionalitas lengkap, tetapi seringkali lebih bertele-tele dan kompleks untuk digunakan.
-
Antar muka sumber daya tingkat yang lebih tinggi tidak menyediakan pemetaan 1-ke-1 dari API layanan yang mendasarinya. Namun, ia menyediakan metode yang membuatnya lebih nyaman bagi Anda untuk mengakses layanan seperti
batch_writer.
Berikut adalah contoh menyisipkan item menggunakan antarmuka klien. Perhatikan bagaimana semua nilai dilewatkan sebagai peta dengan kunci yang menunjukkan jenisnya ('S' untuk string, 'N' untuk angka) dan nilainya sebagai string. Ini dikenal sebagai format DynamoDB JSON.
import boto3 dynamodb = boto3.client('dynamodb') dynamodb.put_item( TableName='YourTableName', Item={ 'pk': {'S': 'id#1'}, 'sk': {'S': 'cart#123'}, 'name': {'S': 'SomeName'}, 'inventory': {'N': '500'}, # ... more attributes ... } )
Inilah PutItem operasi yang sama menggunakan antarmuka sumber daya. Pengetikan data implisit:
import boto3 dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('YourTableName') table.put_item( Item={ 'pk': 'id#1', 'sk': 'cart#123', 'name': 'SomeName', 'inventory': 500, # ... more attributes ... } )
Jika diperlukan, Anda dapat mengonversi antara JSON biasa dan DynamoDB JSON menggunakan TypeDeserializer kelas TypeSerializer dan yang disediakan dengan boto3:
def dynamo_to_python(dynamo_object: dict) -> dict: deserializer = TypeDeserializer() return { k: deserializer.deserialize(v) for k, v in dynamo_object.items() } def python_to_dynamo(python_object: dict) -> dict: serializer = TypeSerializer() return { k: serializer.serialize(v) for k, v in python_object.items() }
Berikut adalah cara melakukan query menggunakan antarmuka klien. Ini mengekspresikan query sebagai konstruksi JSON. Ini menggunakan KeyConditionExpression string yang membutuhkan substitusi variabel untuk menangani konflik kata kunci potensial:
import boto3 client = boto3.client('dynamodb') # Construct the query response = client.query( TableName='YourTableName', KeyConditionExpression='pk = :pk_val AND begins_with(sk, :sk_val)', FilterExpression='#name = :name_val', ExpressionAttributeValues={ ':pk_val': {'S': 'id#1'}, ':sk_val': {'S': 'cart#'}, ':name_val': {'S': 'SomeName'}, }, ExpressionAttributeNames={ '#name': 'name', } )
Operasi kueri yang sama menggunakan antarmuka sumber daya dapat dipersingkat dan disederhanakan:
import boto3 from boto3.dynamodb.conditions import Key, Attr dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('YourTableName') response = table.query( KeyConditionExpression=Key('pk').eq('id#1') & Key('sk').begins_with('cart#'), FilterExpression=Attr('name').eq('SomeName') )
Sebagai contoh terakhir, bayangkan Anda ingin mendapatkan perkiraan ukuran tabel (yang merupakan metadata yang disimpan di tabel yang diperbarui setiap 6 jam). Dengan antarmuka klien, Anda melakukan describe_table() operasi dan menarik jawaban dari struktur JSON yang dikembalikan:
import boto3 dynamodb = boto3.client('dynamodb') response = dynamodb.describe_table(TableName='YourTableName') size = response['Table']['TableSizeBytes']
Dengan antarmuka sumber daya, tabel melakukan operasi deskripsi secara implisit dan menyajikan data secara langsung sebagai atribut:
import boto3 dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('YourTableName') size = table.table_size_bytes
catatan
Saat mempertimbangkan apakah akan mengembangkan menggunakan antarmuka klien atau sumber daya, ketahuilah bahwa fitur baru tidak akan ditambahkan ke antarmuka sumber daya sesuai dokumentasi sumber daya
Menggunakan sumber daya tabel batch_writer
Satu kenyamanan yang hanya tersedia dengan sumber daya tabel tingkat yang lebih tinggi adalah. batch_writer DynamoDB mendukung operasi penulisan batch yang memungkinkan hingga 25 operasi put atau delete dalam satu permintaan jaringan. Batching seperti ini meningkatkan efisiensi dengan meminimalkan perjalanan pulang-pergi jaringan.
Dengan pustaka klien tingkat rendah, Anda menggunakan client.batch_write_item() operasi untuk menjalankan batch. Anda harus membagi pekerjaan Anda secara manual menjadi 25 kelompok. Setelah setiap operasi, Anda juga harus meminta untuk menerima daftar item yang belum diproses (beberapa operasi penulisan mungkin berhasil sementara yang lain bisa gagal). Anda kemudian harus meneruskan item yang belum diproses itu lagi ke batch_write_item() operasi selanjutnya. Ada sejumlah besar kode boilerplate.
Metode
dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('YourTableName') movies = # long list of movies in {'pk': 'val', 'sk': 'val', etc} format with table.batch_writer() as writer: for movie in movies: writer.put_item(Item=movie)
Contoh kode tambahan yang mengeksplorasi lapisan klien dan sumber daya
Anda juga dapat merujuk ke repositori contoh kode berikut yang mengeksplorasi penggunaan berbagai fungsi, menggunakan klien dan sumber daya:
Memahami bagaimana objek Klien dan Sumber Daya berinteraksi dengan sesi dan utas
-
Klien umumnya aman untuk thread setelah dibuat, terlepas dari beberapa fitur canggih. Anda dapat membuat satu Klien dan memanggilnya dari banyak utas pada saat yang bersamaan. Untuk informasi selengkapnya tentang pengecualian ini, lihat panduan tentang Klien
dalam dokumentasi Boto3. -
Sumber Daya tidak aman untuk thread. Sebuah objek Resource tunggal tidak boleh digunakan oleh lebih dari satu thread. Untuk informasi selengkapnya, lihat panduan tentang Sumber Daya
dalam dokumentasi Boto3. -
S esi tidak aman untuk thread. Risikonya adalah dalam membuat Klien atau Sumber Daya darinya: dua utas yang membangunnya dari Sesi yang sama pada saat yang sama dapat menyebabkan respons yang tidak teratur atau crash di lapisan SSL yang mendasarinya. Menciptakannya satu per satu dari Sesi baik-baik saja. Untuk informasi selengkapnya, lihat panduan tentang Sesi
dalam dokumentasi Boto3.
Jika Anda tidak membuat Sesi Anda sendiri, boto3.resource() dan boto3.client() menggunakan Sesi default bersama. Itu baik-baik saja dalam kode utas tunggal, tetapi dalam kode multi-utas setiap utas membangun objek dari Sesi yang sama, yang merupakan pola tidak aman yang dijelaskan sebelumnya.
Bagikan satu Klien di seluruh thread
Karena Klien aman untuk thread, pendekatan paling sederhana dan paling efisien adalah membuat satu Klien di utas utama Anda dan menyerahkannya kepada setiap pekerja. Mereka semua berbagi satu kumpulan koneksi.
Dibuat sekali, di utas utama, lalu dibagikan dengan semua utas:
session = boto3.Session() client = session.client("dynamodb")
Berikan setiap thread sumber dayanya sendiri
Karena Resource tidak aman untuk thread, setiap thread membutuhkannya sendiri. Buat Sesi baru di dalam thread dan buat Sumber Daya darinya, jadi tidak ada dua thread yang membangun Sumber Daya dari Sesi yang sama sekaligus.
Berjalan di dalam setiap utas:
session = boto3.Session() dynamodb = session.resource("dynamodb")
Menyesuaikan objek Config
Saat membangun objek Client atau Resource, Anda dapat meneruskan parameter bernama opsional untuk menyesuaikan perilaku. Parameter bernama config membuka berbagai fungsi. Ini adalah contoh botocore.client.Config dan dokumentasi referensi untuk Config
catatan
Anda dapat memodifikasi banyak pengaturan perilaku ini di tingkat Sesi, dalam file AWS konfigurasi, atau sebagai variabel lingkungan.
Konfigurasi untuk batas waktu
Salah satu penggunaan konfigurasi khusus adalah untuk menyesuaikan perilaku jaringan:
-
connect_timeout (float atau int) — Waktu dalam detik hingga pengecualian batas waktu dilemparkan saat mencoba membuat koneksi. Bawaannya adalah 60 detik.
-
read_timeout (float atau int) — Waktu dalam detik hingga pengecualian batas waktu dilemparkan saat mencoba membaca dari koneksi. Bawaannya adalah 60 detik.
Batas waktu 60 detik berlebihan untuk DynamoDB. Ini berarti kesalahan jaringan sementara akan menyebabkan penundaan satu menit bagi klien sebelum dapat mencoba lagi. Kode berikut mempersingkat batas waktu menjadi 10 detik:
import boto3 from botocore.config import Config my_config = Config( connect_timeout = 10.0, read_timeout = 10.0 ) dynamodb = boto3.resource('dynamodb', config=my_config)
Untuk diskusi selengkapnya tentang batas waktu, lihat Menyetel pengaturan permintaan HTTP AWS Java SDK untuk aplikasi DynamoDB yang sadar latensi.
Konfigurasi untuk keep-alive
Jika Anda menggunakan botocore 1.27.84 atau yang lebih baru, Anda juga dapat mengontrol TCP: Keep-Alive
-
tcp_keepalive (bool) - Mengaktifkan opsi Keep-Alive soket TCP yang digunakan saat membuat koneksi baru jika disetel ke (default ke).
TrueFalseIni hanya tersedia mulai dengan botocore 1.27.84.
Menyetel TCP Keep-Alive untuk True dapat mengurangi latensi rata-rata. Berikut contoh kode yang secara kondisional menetapkan TCP Keep-Alive ke true ketika Anda memiliki versi botocore yang tepat:
import botocore import boto3 from botocore.config import Config required_version = "1.27.84" current_version = botocore.__version__ my_config = Config( connect_timeout = 0.5, read_timeout = 0.5 ) if tuple(map(int, current_version.split("."))) >= tuple(map(int, required_version.split("."))): my_config = my_config.merge(Config(tcp_keepalive = True)) dynamodb = boto3.resource('dynamodb', config=my_config)
catatan
TCP Keep-Alive berbeda dengan HTTP Keep-Alive. Dengan TCP Keep-Alive, paket-paket kecil dikirim oleh sistem operasi yang mendasarinya melalui koneksi soket untuk menjaga koneksi tetap hidup dan segera mendeteksi setiap tetes. Dengan HTTP Keep-Alive, koneksi web yang dibangun pada soket yang mendasarinya akan digunakan kembali. HTTP selalu Keep-Alive diaktifkan dengan boto3.
Ada batasan berapa lama koneksi idle dapat tetap hidup. Pertimbangkan untuk mengirim permintaan berkala (katakanlah setiap menit) jika Anda memiliki koneksi idle tetapi ingin permintaan berikutnya menggunakan koneksi yang sudah dibuat.
Konfigurasi untuk percobaan ulang
Konfigurasi juga menerima kamus yang disebut percobaan ulang di mana Anda dapat menentukan perilaku coba ulang yang Anda inginkan. Percobaan ulang terjadi di dalam SDK ketika SDK menerima kesalahan dan kesalahannya adalah tipe sementara. Jika kesalahan dicoba ulang secara internal (dan percobaan ulang akhirnya menghasilkan respons yang berhasil), tidak ada kesalahan yang terlihat dari perspektif kode panggilan, hanya latensi yang sedikit meningkat. Berikut adalah nilai-nilai yang dapat Anda tentukan:
-
max_ — Bilangan bulat yang mewakili jumlah maksimum upaya percobaan ulang yang akan dilakukan pada satu permintaan. Misalnya, menyetel nilai ini ke 2 akan mengakibatkan permintaan dicoba ulang paling banyak dua kali setelah permintaan awal. Menyetel nilai ini ke 0 akan menghasilkan tidak ada percobaan ulang yang pernah dicoba setelah permintaan awal.
-
total_max_ — Bilangan bulat yang mewakili jumlah maksimum total upaya yang akan dilakukan pada satu permintaan. Ini termasuk permintaan awal, jadi nilai 1 menunjukkan bahwa tidak ada permintaan yang akan dicoba lagi. Jika
total_max_attemptsdanmax_attemptskeduanya disediakan, diuttotal_max_attemptsamakan.total_max_attemptslebih disukaimax_attemptskarena memetakan ke variabelAWS_MAX_ATTEMPTSlingkungan dan nilai filemax_attemptskonfigurasi. -
mode — Sebuah string yang mewakili jenis mode coba ulang yang harus digunakan botocore. Nilai yang valid adalah:
-
legacy — Mode default. Menunggu 50ms percobaan ulang pertama, kemudian menggunakan backoff eksponensial dengan faktor dasar 2. Untuk DynamoDB, ia melakukan hingga 10 total upaya maksimal (kecuali diganti dengan yang di atas).
catatan
Dengan mundur eksponensial, upaya terakhir akan menunggu hampir 13 detik.
-
standar — Dinamakan standar karena lebih konsisten dengan AWS SDK lain. Menunggu waktu acak dari 0ms hingga 1.000ms untuk percobaan ulang pertama. Jika percobaan ulang lain diperlukan, ia memilih waktu acak lain dari 0ms hingga 1.000ms dan mengalikannya dengan 2. Jika percobaan ulang tambahan diperlukan, ia melakukan pilihan acak yang sama dikalikan dengan 4, dan seterusnya. Setiap penantian dibatasi pada 20 detik. Mode ini akan melakukan percobaan ulang pada kondisi kegagalan yang lebih terdeteksi daripada
legacymode. Untuk DynamoDB, ia melakukan hingga 3 total upaya maksimal (kecuali diganti dengan yang di atas). -
adaptif - Mode coba ulang eksperimental yang mencakup semua fungsionalitas mode standar tetapi menambahkan pelambatan sisi klien otomatis. Dengan pembatasan kecepatan adaptif, SDK dapat memperlambat laju pengiriman permintaan untuk mengakomodasi kapasitas AWS layanan dengan lebih baik. Ini adalah mode sementara yang perilakunya mungkin berubah.
-
Definisi yang diperluas dari mode coba ulang ini dapat ditemukan di panduan untuk mencoba ulang
Berikut contoh yang secara eksplisit menggunakan kebijakan legacy coba ulang dengan maksimal 3 permintaan total (2 percobaan ulang):
import boto3 from botocore.config import Config my_config = Config( connect_timeout = 1.0, read_timeout = 1.0, retries = { 'mode': 'legacy', 'total_max_attempts': 3 } ) dynamodb = boto3.resource('dynamodb', config=my_config)
Karena DynamoDB adalah sistem latensi rendah yang sangat tersedia, Anda mungkin ingin lebih agresif dengan kecepatan percobaan ulang daripada yang diizinkan oleh kebijakan coba ulang bawaan. Anda dapat menerapkan kebijakan coba ulang Anda sendiri dengan menyetel upaya maksimal ke 0, menangkap pengecualian sendiri, dan mencoba lagi sesuai dengan kode Anda sendiri alih-alih mengandalkan boto3 untuk melakukan percobaan ulang implisit.
Jika Anda mengelola kebijakan coba ulang sendiri, Anda harus membedakan antara throttle dan error:
-
Throttle (ditunjukkan dengan
ProvisionedThroughputExceededExceptionatauThrottlingException) menunjukkan layanan sehat yang memberi tahu Anda bahwa Anda telah melampaui kapasitas baca atau tulis pada tabel atau partisi DynamoDB. Setiap milidetik yang berlalu, sedikit lebih banyak kapasitas baca atau tulis tersedia, sehingga Anda dapat mencoba lagi dengan cepat (seperti setiap 50 ms) untuk mencoba mengakses kapasitas yang baru dirilis. Dengan throttle, Anda tidak memerlukan backoff eksponensial karena throttle ringan untuk dikembalikan DynamoDB dan tidak dikenakan biaya per permintaan kepada Anda. Backoff eksponensial menetapkan penundaan yang lebih lama ke utas klien yang telah menunggu paling lama, yang secara statistik memperluas p50 dan p99 ke luar. -
Kes alahan (ditunjukkan oleh a
InternalServerErroratau aServiceUnavailable, antara lain) menunjukkan masalah sementara dengan layanan. Ini bisa untuk seluruh tabel atau mungkin hanya partisi tempat Anda membaca atau menulis. Dengan kesalahan, Anda dapat menjeda lebih lama sebelum mencoba lagi (seperti 250ms atau 500ms) dan menggunakan jitter untuk mengacaukan percobaan ulang.
Untuk informasi tentang perubahan mendatang pada perilaku coba ulang default di semua AWS
SDK, lihat Mengumumkan perilaku coba ulang yang diperbarui untuk AWS SDK dan Alat
Konfigurasi untuk koneksi pool maksimal
Terakhir, konfigurasi memungkinkan Anda mengontrol ukuran kumpulan koneksi:
-
max_pool_connections (int) — Jumlah maksimum koneksi yang disimpan dalam kumpulan koneksi. Jika nilai ini tidak disetel, nilai default 10 digunakan.
Opsi ini mengontrol jumlah maksimum koneksi HTTP agar tetap dikumpulkan untuk digunakan kembali. Kumpulan yang berbeda disimpan untuk setiap Klien. Jika thread pada Klien menginginkan koneksi dan kumpulan kosong, itu akan membuat koneksi baru. Jika thread mencoba mengembalikan koneksi ke kolam setelah digunakan dan menemukan kolam penuh, itu akan menutup koneksi. Bila Anda mengantisipasi lebih dari 10 thread melawan satu Klien, pertimbangkan untuk menaikkan ukuran kumpulan agar sesuai dengan jumlah thread.
import boto3 from botocore.config import Config my_config = Config( max_pool_connections = 20 ) session = boto3.Session() # One client with a larger connection pool client = session.client("dynamodb", config=my_config)
Setiap Resource juga memiliki kumpulan koneksi di dalamnya, tetapi objek Resource tidak aman untuk thread, jadi jangan bagikan di seluruh thread. Berikan setiap thread sumber dayanya sendiri.
Penanganan kesalahan
AWS pengecualian layanan tidak semuanya didefinisikan secara statis di Boto3. Ini karena kesalahan dan pengecualian dari AWS layanan sangat bervariasi dan dapat berubah. Boto3 membungkus semua pengecualian layanan sebagai ClientError a dan memperlihatkan detail sebagai JSON terstruktur. Misalnya, respons kesalahan mungkin terstruktur seperti ini:
{ 'Error': { 'Code': 'SomeServiceException', 'Message': 'Details/context around the exception or error' }, 'ResponseMetadata': { 'RequestId': '1234567890ABCDEF', 'HostId': 'host ID data will appear here as a hash', 'HTTPStatusCode': 400, 'HTTPHeaders': {'header metadata key/values will appear here'}, 'RetryAttempts': 0 } }
Kode berikut menangkap ClientError pengecualian apa pun dan melihat nilai string di Code dalam Error untuk menentukan tindakan apa yang harus diambil:
import botocore import boto3 dynamodb = boto3.client('dynamodb') try: response = dynamodb.put_item(...) except botocore.exceptions.ClientError as err: print('Error Code: {}'.format(err.response['Error']['Code'])) print('Error Message: {}'.format(err.response['Error']['Message'])) print('Http Code: {}'.format(err.response['ResponseMetadata']['HTTPStatusCode'])) print('Request ID: {}'.format(err.response['ResponseMetadata']['RequestId'])) if err.response['Error']['Code'] in ('ProvisionedThroughputExceededException', 'ThrottlingException'): print("Received a throttle") elif err.response['Error']['Code'] == 'InternalServerError': print("Received a server error") else: raise err
Beberapa (tetapi tidak semua) kode pengecualian telah diwujudkan sebagai kelas tingkat atas. Anda dapat memilih untuk menangani ini secara langsung. Saat menggunakan antarmuka Klien, pengecualian ini diisi secara dinamis pada klien Anda dan Anda menangkap pengecualian ini menggunakan instance klien Anda, seperti ini:
except ddb_client.exceptions.ProvisionedThroughputExceededException:
Saat menggunakan antarmuka Sumber Daya, Anda harus menggunakan untuk melintasi dari sumber daya .meta.client ke Klien yang mendasarinya untuk mengakses pengecualian, seperti ini:
except ddb_resource.meta.client.exceptions.ProvisionedThroughputExceededException:
Untuk meninjau daftar jenis pengecualian yang terwujud, Anda dapat membuat daftar secara dinamis:
ddb = boto3.client("dynamodb") print([e for e in dir(ddb.exceptions) if e.endswith('Exception') or e.endswith('Error')])
Saat melakukan operasi tulis dengan ekspresi kondisi, Anda dapat meminta bahwa jika ekspresi gagal nilai item harus dikembalikan dalam respons kesalahan.
try: response = table.put_item( Item=item, ConditionExpression='attribute_not_exists(pk)', ReturnValuesOnConditionCheckFailure='ALL_OLD' ) except table.meta.client.exceptions.ConditionalCheckFailedException as e: print('Item already exists:', e.response['Item'])
Untuk bacaan lebih lanjut tentang penanganan kesalahan dan pengecualian:
-
Panduan boto3 tentang penanganan kesalahan
memiliki informasi lebih lanjut tentang teknik penanganan kesalahan. -
Bagian panduan pengembang DynamoDB tentang kesalahan pemrograman mencant umkan kesalahan apa yang mungkin Anda temui.
-
Dokumentasi pada setiap operasi API mencantumkan kesalahan apa yang mungkin dihasilkan oleh panggilan (misalnya BatchWriteItem).
Pencatatan log
Pustaka boto3 terintegrasi dengan modul logging bawaan Python untuk melacak apa yang terjadi selama sesi. Untuk mengontrol level logging, Anda dapat mengonfigurasi modul logging:
import logging logging.basicConfig(level=logging.INFO)
Ini mengonfigurasi root logger untuk mencatat INFO dan pesan tingkat di atas. Pencatatan pesan yang kurang parah dari level akan diabaikan. Level logging termasukDEBUG,INFO,WARNING,ERROR, danCRITICAL. Nilai default-nya WARNING.
Logger di boto3 bersifat hierarkis. Perpustakaan menggunakan beberapa pencatat yang berbeda, masing-masing sesuai dengan bagian perpustakaan yang berbeda. Anda dapat secara terpisah mengontrol perilaku masing-masing:
-
boto3: Logger utama untuk modul boto3.
-
botocore: Logger utama untuk paket botocore.
-
botocore.auth: Digunakan untuk mencatat pembuatan tanda tangan untuk permintaan. AWS
-
botocore.: Digunakan untuk mencatat proses pengambilan dan penyegaran kredensia.
-
botocore.endpoint: Digunakan untuk mencatat pembuatan permintaan sebelum dikirim melalui jaringan.
-
botocore.hooks: Digunakan untuk mencatat peristiwa yang dipicu di perpustakaan.
-
botocore.loaders: Digunakan untuk mencatat saat bagian-bagian model layanan dimuat. AWS
-
botocore.parsers: Digunakan untuk mencatat respons AWS layanan sebelum diurai.
-
botocore.retryhandler: Digunakan untuk mencatat pemrosesan percobaan ulang permintaan AWS layanan (mode lama).
-
botocore.retries.standard: Digunakan untuk mencatat pemrosesan percobaan ulang permintaan AWS layanan (mode standar atau adaptif).
-
botocore.utils: Digunakan untuk mencatat aktivitas lain-lain di perpustakaan.
-
botocore.waiter: Digunakan untuk mencatat fungsionalitas pelayan, yang melakukan polling AWS layanan sampai keadaan tertentu tercapai.
Perpustakaan lain juga mencatat. Secara internal, boto3 menggunakan urllib3 pihak ketiga untuk penanganan koneksi HTTP. Ketika latensi penting, Anda dapat menonton lognya untuk memastikan kumpulan Anda dimanfaatkan dengan baik dengan melihat kapan urllib3 membuat koneksi baru atau menutup koneksi idle.
-
urllib3.connectionpool: Dig unakan untuk mencatat peristiwa penanganan kumpulan koneksi.
Cuplikan kode berikut menyetel sebagian besar logging ke INFO dengan DEBUG logging untuk titik akhir dan aktivitas kumpulan koneksi:
import logging logging.getLogger('boto3').setLevel(logging.INFO) logging.getLogger('botocore').setLevel(logging.INFO) logging.getLogger('botocore.endpoint').setLevel(logging.DEBUG) logging.getLogger('urllib3.connectionpool').setLevel(logging.DEBUG)
Pengait acara
Botocore memancarkan peristiwa selama berbagai bagian pelaksanaannya. Anda dapat mendaftarkan penangan untuk peristiwa ini sehingga setiap kali peristiwa dipancarkan, handler Anda akan dipanggil. Ini memungkinkan Anda memperluas perilaku botocore tanpa harus memodifikasi internal.
Misalnya, katakanlah Anda ingin melacak setiap kali PutItem operasi dipanggil pada tabel DynamoDB apa pun di aplikasi Anda. Anda dapat mendaftar pada 'provide-client-params.dynamodb.PutItem' acara untuk menangkap dan mencatat setiap kali PutItem operasi dipanggil pada Sesi terkait. Inilah contohnya:
import boto3 import botocore import logging def log_put_params(params, **kwargs): if 'TableName' in params and 'Item' in params: logging.info(f"PutItem on table {params['TableName']}: {params['Item']}") logging.basicConfig(level=logging.INFO) session = boto3.Session() event_system = session.events # Register our interest in hooking in when the parameters are provided to PutItem event_system.register('provide-client-params.dynamodb.PutItem', log_put_params) # Now, every time you use this session to put an item in DynamoDB, # it will log the table name and item data. dynamodb = session.resource('dynamodb') table = dynamodb.Table('YourTableName') table.put_item( Item={ 'pk': '123', 'sk': 'cart#123', 'item_data': 'YourItemData', # ... more attributes ... } )
Di dalam handler, Anda bahkan dapat memanipulasi parameter secara terprogram untuk mengubah perilaku:
params['TableName'] = "NewTableName"
Untuk informasi selengkapnya tentang acara, lihat dokumentasi botocore tentang peristiwa
Pagination dan Paginator
Beberapa permintaan, seperti Query dan Scan, membatasi ukuran data yang dikembalikan pada satu permintaan dan mengharuskan Anda membuat permintaan berulang untuk menarik halaman berikutnya.
Anda dapat mengontrol jumlah maksimum item yang akan dibaca untuk setiap halaman dengan limit parameter. Misalnya, jika Anda ingin 10 item terakhir, Anda dapat menggunakan limit untuk mengambil hanya 10 yang terakhir. Perhatikan batasnya adalah berapa banyak yang harus dibaca dari tabel sebelum penyaringan diterapkan. Tidak ada cara untuk menentukan Anda ingin tepat 10 setelah pemfilteran; Anda hanya dapat mengontrol jumlah pra-filter dan memeriksa sisi klien ketika Anda benar-benar mengambil 10. Terlepas dari batasnya, setiap respons selalu memiliki ukuran maksimum 1 MB.
Jika respons menyertakan aLastEvaluatedKey, itu menunjukkan respons berakhir karena mencapai batas jumlah atau ukuran. Kuncinya adalah kunci terakhir yang dievaluasi untuk respons. Anda dapat mengambil ini LastEvaluatedKey dan meneruskannya ke panggilan tindak lanjut ExclusiveStartKey untuk membaca potongan berikutnya dari titik awal itu. Ketika tidak ada yang LastEvaluatedKey dikembalikan itu, berarti tidak ada lagi item yang cocok dengan Query atau Scan.
Berikut adalah contoh sederhana (menggunakan antarmuka Sumber Daya, tetapi antarmuka Klien memiliki pola yang sama) yang membaca paling banyak 100 item per halaman dan berputar sampai semua item telah dibaca.
import boto3 from boto3.dynamodb.conditions import Key dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('YourTableName') query_params = { 'KeyConditionExpression': Key('pk').eq('123') & Key('sk').gt(1000), 'Limit': 100 } while True: response = table.query(**query_params) # Process the items however you like for item in response['Items']: print(item) # No LastEvaluatedKey means no more items to retrieve if 'LastEvaluatedKey' not in response: break # If there are possibly more items, update the start key for the next page query_params['ExclusiveStartKey'] = response['LastEvaluatedKey']
Untuk kenyamanan, boto3 dapat melakukan ini untuk Anda dengan Paginator. Namun, ini hanya berfungsi dengan antarmuka Klien. Berikut kode yang ditulis ulang untuk menggunakan Paginator:
import boto3 dynamodb = boto3.client('dynamodb') paginator = dynamodb.get_paginator('query') query_params = { 'TableName': 'YourTableName', 'KeyConditionExpression': 'pk = :pk_val AND sk > :sk_val', 'ExpressionAttributeValues': { ':pk_val': {'S': '123'}, ':sk_val': {'N': '1000'}, }, 'Limit': 100 } page_iterator = paginator.paginate(**query_params) for page in page_iterator: # Process the items however you like for item in page['Items']: print(item)
Untuk informasi selengkapnya, lihat Panduan tentang Paginator
catatan
Paginator juga memiliki pengaturan konfigurasi mereka sendiri bernamaMaxItems,StartingToken, dan. PageSize Untuk membuat paginasi dengan DynamoDB, Anda harus mengabaikan pengaturan ini.
Pelayan
Pelayan memberikan kemampuan untuk menunggu sesuatu selesai sebelum melanjutkan. Saat ini, mereka hanya mendukung menunggu tabel dibuat atau dihapus. Di latar belakang, operasi pelayan melakukan pemeriksaan untuk Anda setiap 20 detik hingga 25 kali. Anda bisa melakukannya sendiri, tetapi menggunakan pelayan itu elegan saat menulis otomatisasi.
Kode ini menunjukkan cara menunggu tabel tertentu dibuat:
# Create a table, wait until it exists, and print its ARN response = client.create_table(...) waiter = client.get_waiter('table_exists') waiter.wait(TableName='YourTableName') print('Table created:', response['TableDescription']['TableArn'])
Untuk informasi lebih lanjut, lihat Panduan Pelayan