本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 Python 和 Boto3 程式設計 Amazon DynamoDB
本指南提供程式設計人員想要搭配 Python 使用 Amazon DynamoDB 的方向。了解不同的抽象層、組態管理、錯誤處理、控制重試政策、管理保持連線等。
主題
關於 Boto
您可以使用適用於 Python 的官方 AWS SDK,從 Python 存取 DynamoDB,通常稱為 Boto3。Boto (發音 boh-toh) 的名稱來自 Amazon River 原生的淡水海豚。Boto3 程式庫是程式庫的第三個主要版本,於 2015 年首次發行。Boto3 程式庫相當大,因為它支援所有 AWS 服務,而不只是 DynamoDB。此方向僅針對與 DynamoDB 相關的 Boto3 部分。
Boto 由 維護和發佈 AWS ,做為託管在 GitHub 上的開放原始碼專案。它分為兩個套件:Botocore
-
Botocore 提供低階功能。在 Botocore 中,您會找到用戶端、工作階段、登入資料、組態和例外類別。
-
Boto3 建置於 Botocore 之上。它提供更高層級、更 Pythonic 的界面。具體而言,它公開 DynamoDB 資料表做為資源,並提供比較低層級、服務導向的用戶端界面更簡單、更優雅的界面。
由於這些專案託管在 GitHub 上,因此您可以檢視原始碼、追蹤開啟的問題,或提交您自己的問題。
使用 Boto 文件
使用下列資源開始使用 Boto 文件:
-
從 Quickstart 區段開始,該區段
提供套件安裝的堅實起點。前往 以取得在尚未安裝 Boto3 時安裝的指示 (Boto3 通常可在 等 AWS 服務內自動使用 AWS Lambda)。 -
之後,請專注於文件的 DynamoDB 指南
。它說明如何執行基本 DynamoDB 活動:建立和刪除資料表、操作項目、執行批次操作、執行查詢,以及執行掃描。其範例使用 資源界面。當您看到 boto3.resource('dynamodb')
表示您正在使用更高層級的資源界面時。 -
在本指南之後,您可以檢閱 DynamoDB 參考
。此登陸頁面提供您可使用的類別和方法的詳盡清單。在頂端,您會看到 DynamoDB.Client
類別。這可讓您低階存取所有控制平面和資料平面操作。在底部查看DynamoDB.ServiceResource
類別。這是更高層級的 Pythonic 介面。您可以使用它建立資料表、跨資料表執行批次操作,或取得資料表特定動作的DynamoDB.ServiceResource.Table
執行個體。
了解用戶端和資源抽象層
您將使用的兩個界面是用戶端界面和資源界面。
-
低階用戶端界面提供基礎服務 API 的 1:1 映射。DynamoDB 提供的每個 API 都可以透過用戶端取得。這表示用戶端界面可以提供完整的功能,但通常更詳細且複雜。
-
更高層級的資源界面不提供基礎服務 API 的 1:1 映射。不過,它提供的方法可讓您更方便地存取 服務,例如
batch_writer
。
以下是使用用戶端界面插入項目的範例。請注意,所有值如何以表示其類型的索引鍵 (字串為 'S',數字為 'N') 傳遞,而其值則以字串傳遞。這稱為 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 ... } )
以下是使用 資源界面的相同PutItem
操作。資料輸入是隱含的:
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 ... } )
如有需要,您可以使用 和 boto3 提供的TypeDeserializer
類別,在一般 JSON TypeSerializer
和 DynamoDB JSON 之間轉換:
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() }
以下是如何使用用戶端界面執行查詢。它將查詢表達為 JSON 建構。它使用需要變數取代的KeyConditionExpression
字串來處理任何潛在的關鍵字衝突:
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', } )
使用 資源界面的相同查詢操作可以縮短和簡化:
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') )
最後,假設您想要取得資料表的大致大小 (這是保留在資料表上的中繼資料,大約每 6 小時更新一次)。使用用戶端界面,您可以執行 describe_table()
操作,並從傳回的 JSON 結構中提取答案:
import boto3 dynamodb = boto3.client('dynamodb') response = dynamodb.describe_table(TableName='YourTableName') size = response['Table']['TableSizeBytes']
使用 資源界面,資料表會隱含地執行描述操作,並直接將資料顯示為 屬性:
import boto3 dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('YourTableName') size = table.table_size_bytes
注意
考慮使用用戶端或資源界面進行開發時,請注意,根據資源文件
使用資料表資源 batch_writer
一個只有更高層級的資料表資源才可用的便利性是 batch_writer
。DynamoDB 支援批次寫入操作,可在一個網路請求中最多放置或刪除 25 個操作。像這樣的批次處理可最大限度地減少網路往返,進而提高效率。
使用低階用戶端程式庫時,您可以使用 client.batch_write_item()
操作來執行批次。您必須手動將工作分割為 25 個批次。在每次操作後,您也必須請求 接收未處理項目的清單 (有些寫入操作可能會成功,而其他操作可能會失敗)。然後,您必須將這些未處理的項目再次傳遞至稍後batch_write_item()
的操作。有大量的樣板程式碼。
Table.batch_writer
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)
探索用戶端和資源層的其他程式碼範例
您也可以參考下列程式碼範例儲存庫,以探索各種函數的使用情況,同時使用用戶端和資源:
了解用戶端和資源物件如何與工作階段和執行緒互動
資源物件不安全,不應跨執行緒或程序共用。如需詳細資訊,請參閱 資源指南
相反地,用戶端物件通常可以安全執行緒,但特定進階功能除外。如需詳細資訊,請參閱 用戶端的指南
工作階段物件執行緒不安全。因此,每次在多執行緒環境中建立用戶端或資源時,您應先建立新的工作階段,然後從工作階段建立用戶端或資源。如需詳細資訊,請參閱工作階段指南
當您呼叫 時boto3.resource()
,您會隱含地使用預設工作階段。這對於編寫單執行緒程式碼非常方便。撰寫多執行緒程式碼時,您會想要先為每個執行緒建構新的工作階段,然後從該工作階段擷取資源:
# Explicitly create a new Session for this thread session = boto3.Session() dynamodb = session.resource('dynamodb')
自訂 Config 物件
建構用戶端或資源物件時,您可以傳遞選用的具名參數來自訂行為。名為 的 參數會config
解除鎖定各種功能。這是 的執行個體,botocore.client.Config
而 Config 的參考文件
注意
您可以在工作階段層級、 AWS 組態檔案內或作為環境變數修改許多這些行為設定。
逾時的組態
自訂組態的其中一個用途是調整聯網行為:
-
connect_timeout (浮點數或整數) – 在嘗試建立連線時,擲出逾時例外狀況的秒數。預設值為 60 秒。
-
read_timeout (浮點數或整數) – 嘗試從連線讀取時,捨棄逾時例外狀況的秒數。預設值為 60 秒。
DynamoDB 的 60 秒逾時過多。這表示暫時性網路故障會導致用戶端延遲一分鐘,然後再試。下列程式碼會將逾時縮短為一秒:
import boto3 from botocore.config import Config my_config = Config( connect_timeout = 1.0, read_timeout = 1.0 ) dynamodb = boto3.resource('dynamodb', config=my_config)
如需逾時的更多討論,請參閱調整延遲感知 DynamoDB 應用程式的 AWS Java SDK HTTP 請求設定
保持連線的組態
如果您使用的是 botocore 1.27.84 或更新版本,您也可以控制 TCP Keep-Alive:
-
tcp_keepalive (bool) - 啟用 TCP Keep-Alive 通訊端選項,如果設定為
True
( 預設為False
),則建立新連線時使用。這僅適用於從 botocore 1.27.84 開始。
將 TCP Keep-Alive 設定為 True
可減少平均延遲。以下是範例程式碼,當您有正確的 botocore 版本時,將 TCP Keep-Alive 設定為 true:
import botocore import boto3 from botocore.config import Config from distutils.version import LooseVersion required_version = "1.27.84" current_version = botocore.__version__ my_config = Config( connect_timeout = 0.5, read_timeout = 0.5 ) if LooseVersion(current_version) > LooseVersion(required_version): my_config = my_config.merge(Config(tcp_keepalive = True)) dynamodb = boto3.resource('dynamodb', config=my_config)
注意
TCP Keep-Alive 與 HTTP Keep-Alive 不同。使用 TCP Keep-Alive 時,基礎作業系統會透過通訊端連線傳送小型封包,以保持連線運作並立即偵測任何下降情況。使用 HTTP Keep-Alive 時,會重複使用基礎通訊端上建置的 Web 連線。HTTP Keep-Alive 一律使用 boto3 啟用。
閒置連線可以保持運作的時間有限制。如果您有閒置連線,但希望下一個請求使用已建立的連線,請考慮定期傳送請求 (每分鐘傳送一次)。
重試的組態
此組態也接受名為重試的字典,您可以在其中指定所需的重試行為。當 SDK 收到錯誤且錯誤為暫時性類型時,軟體開發套件內會發生重試。如果在內部重試錯誤 (重試最終產生成功的回應),從呼叫程式碼的角度來看就不會看到錯誤,只是延遲稍微增加。以下是您可以指定的值:
-
max_attempts – 整數,代表單一請求的重試嘗試次數上限。例如,將此值設定為 2 會導致在初始請求後重試請求最多兩次。將此值設定為 0 將導致在初始請求之後,不會嘗試任何重試。
-
total_max_attempts – 整數,代表單一請求的嘗試總數上限。這包括初始請求,因此值為 1 表示不會重試任何請求。如果同時提供
max_attempts
total_max_attempts
和 ,則total_max_attempts
優先。total_max_attempts
優先於max_attempts
,max_attempts
因為它映射到AWS_MAX_ATTEMPTS
環境變數和組態檔案值。 -
mode – 代表重試模式 botocore 應該使用的類型字串。有效的 值如下:
-
舊版 – 預設模式。等待第一次重試的 50 毫秒,然後使用指數退避,基本係數為 2。對於 DynamoDB,它最多執行總計 10 次嘗試 (除非以上述覆寫)。
注意
使用指數退避時,最後一次嘗試將會等待近 13 秒。
-
標準 – 具名標準,因為它更符合其他 AWS SDKs。第一次重試的隨機等待時間從 0 毫秒到 1,000 毫秒。如果需要再次重試,它會挑選從 0 毫秒到 1,000 毫秒的另一個隨機時間,然後乘以 2。如果需要額外的重試,它會執行相同的隨機挑選乘以 4,以此類推。每次等待上限為 20 秒。此模式將在比
legacy
模式更多的偵測到失敗情況下執行重試。對於 DynamoDB,它最多執行 3 次嘗試總計 (除非以上述覆寫)。 -
適應性 - 實驗性重試模式,包含標準模式的所有功能,但新增自動用戶端調節。利用適應性速率限制,SDKs可以降低傳送請求的速率,以更好地適應 AWS 服務的容量。這是一種暫時性模式,其行為可能會變更。
-
您可以在 SDK
以下是明確使用legacy
重試政策的範例,請求總數最多為 3 個 (2 次重試):
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)
由於 DynamoDB 是一種高可用性、低延遲的系統,因此您可能想要比內建重試政策允許的速度更積極地處理重試速度。您可以透過將最大嘗試次數設定為 0、自行擷取例外狀況,以及適當從自己的程式碼重試,而不是依賴 boto3 進行隱含重試,來實作您自己的重試政策。
如果您管理自己的重試政策,建議您區分調節和錯誤:
-
調節 (由
ProvisionedThroughputExceededException
或 表示ThrottlingException
) 表示運作狀態良好的服務,通知您已超過 DynamoDB 資料表或分割區上的讀取或寫入容量。每經過一毫秒,就會提供多一點的讀取或寫入容量,因此您可以快速重試 (例如每 50 毫秒),嘗試存取該新發行的容量。使用節流時,您不需要特別指數退避,因為節流很輕量,DynamoDB 可以傳回,而且不會向您收取每次請求的費用。指數退避會將較長的延遲指派給已等待最長時間的用戶端執行緒,以統計方式向外延伸 p50 和 p99。 -
錯誤 (由
InternalServerError
或 表示ServiceUnavailable
,以及其他) 表示服務有暫時性問題。這可以是整個資料表,也可能只是您正在讀取或寫入的分割區。發生錯誤時,您可以在重試之前暫停更長的時間 (例如 250 毫秒或 500 毫秒),並使用抖動來交錯重試。
集區連線上限的組態
最後,組態可讓您控制連線集區大小:
-
max_pool_connections (int) – 在連線集區中保留的連線數目上限。如果未設定此值,則會使用預設值 10。
此選項可控制 HTTP 連線的數目上限,以保持集區以供重複使用。每個工作階段會保留不同的集區。如果您預期超過 10 個執行緒會針對同一工作階段建置的用戶端或資源,您應該考慮提出此問題,因此執行緒不必使用集區連線在其他執行緒上等待。
import boto3 from botocore.config import Config my_config = Config( max_pool_connections = 20 ) # Setup a single session holding up to 20 pooled connections session = boto3.Session(my_config) # Create up to 20 resources against that session for handing to threads # Notice the single-threaded access to the Session and each Resource resource1 = session.resource('dynamodb') resource2 = session.resource('dynamodb') # etc
錯誤處理
AWS Boto3 中並未靜態定義所有服務例外狀況。這是因為 AWS 服務的錯誤和例外狀況差異很大,可能會有所變更。Boto3 將所有服務例外狀況包裝為 ,ClientError
並以結構化 JSON 公開詳細資訊。例如,錯誤回應的結構如下:
{ '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 } }
下列程式碼會擷取任何ClientError
例外狀況,並查看 Code
內 的字串值Error
,以決定要採取的動作:
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
有些 (但不是全部) 例外狀況代碼已具體化為最上層類別。您可以選擇直接處理這些項目。使用用戶端界面時,這些例外狀況會在您的用戶端上動態填入,而您使用用戶端執行個體來擷取這些例外狀況,如下所示:
except ddb_client.exceptions.ProvisionedThroughputExceededException:
使用 資源界面時,您必須使用 .meta.client
從資源周遊到基礎用戶端來存取例外狀況,如下所示:
except ddb_resource.meta.client.exceptions.ProvisionedThroughputExceededException:
若要檢閱具體化例外狀況類型的清單,您可以動態產生清單:
ddb = boto3.client("dynamodb") print([e for e in dir(ddb.exceptions) if e.endswith('Exception') or e.endswith('Error')])
使用條件表達式執行寫入操作時,您可以請求如果表達式失敗,則應在錯誤回應中傳回項目的值。
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'])
如需進一步了解錯誤處理和例外狀況:
-
有關錯誤處理的 boto3 指南
提供錯誤處理技術的詳細資訊。 -
程式設計錯誤的 DynamoDB 開發人員指南區段會列出您可能遇到的錯誤。
-
每個 API 操作的文件會列出呼叫可能產生的錯誤 (例如 BatchWriteItem)。
日誌
boto3 程式庫與 Python 的內建記錄模組整合,以追蹤工作階段期間發生的情況。若要控制記錄層級,您可以設定記錄模組:
import logging logging.basicConfig(level=logging.INFO)
這會將根記錄器設定為記錄 INFO
和更高層級的訊息。系統會忽略較層級不嚴重的記錄訊息。記錄層級包括 DEBUG
、INFO
、ERROR
、 WARNING
和 CRITICAL
。預設值為 WARNING
。
boto3 中的記錄器是階層式的。程式庫使用幾個不同的記錄器,每個對應至程式庫的不同部分。您可以個別控制每個 的行為:
-
boto3:boto3 模組的主要記錄器。
-
botocore:botocore 套件的主要記錄器。
-
botocore.auth:用於記錄 AWS 請求的簽章建立。
-
botocore.credentials:用於記錄憑證擷取和重新整理的程序。
-
botocore.endpoint:用於在透過網路傳送請求之前記錄建立請求。
-
botocore.hooks:用於記錄程式庫中觸發的事件。
-
botocore.loaders:用於在載入部分 AWS 服務模型時記錄。
-
botocore.parsers:用於在剖析之前記錄 AWS 服務回應。
-
botocore.retryhandler:用於記錄 AWS 服務請求重試的處理 (舊版模式)。
-
botocore.retries.standard:用於記錄 AWS 服務請求重試的處理 (標準或適應模式)。
-
botocore.utils:用於記錄程式庫中的其他活動。
-
botocore.waiter:用於記錄等待者的功能,這會輪詢 AWS 服務,直到達到特定狀態為止。
其他程式庫日誌也一樣。在內部,boto3 會使用第三方 urllib3 來處理 HTTP 連線。當延遲很重要時,您可以觀看其日誌,以確保集區在 urllib3 建立新連線或關閉閒置連線時,獲得充分利用。
-
urllib3.connectionpool:使用 記錄連線集區處理事件。
下列程式碼片段會設定 的大多數日誌記錄INFO
,以及端點和連線集區活動的DEBUG
日誌記錄:
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)
事件掛鉤
Botocore 在執行的各個部分期間發出事件。您可以為這些事件註冊處理常式,以便每次發出事件時,都會呼叫您的處理常式。這可讓您擴充 botocore 的行為,而不必修改內部。
例如,假設您想要追蹤每次在應用程式中任何 DynamoDB 資料表上呼叫PutItem
操作時。您可以在'provide-client-params.dynamodb.PutItem'
事件上註冊,以在每次在關聯的工作階段上叫用PutItem
操作時擷取和記錄。範例如下:
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 ... } )
在處理常式中,您甚至可以透過程式設計方式操作參數來變更行為:
params['TableName'] = "NewTableName"
如需事件的詳細資訊,請參閱事件的 botocore 文件
分頁和分頁程式
有些請求,例如查詢和掃描,會限制單一請求上傳回的資料大小,並要求您重複提出請求以提取後續頁面。
您可以使用 limit
參數控制每個頁面要讀取的項目數量上限。例如,如果您想要最後 10 個項目,您可以使用 limit
僅擷取最後 10 個項目。請注意,限制是套用任何篩選之前,應該從資料表讀取多少。篩選後無法指定您想要的確切 10;您只能控制預先篩選的計數,並在實際擷取 10 時檢查用戶端。無論限制為何,每個回應的大小一律上限為 1 MB。
如果回應包含 LastEvaluatedKey
,則表示回應因為達到計數或大小限制而結束。金鑰是針對回應評估的最後一個金鑰。您可以擷取此項目,LastEvaluatedKey
並將其傳遞至後續呼叫ExclusiveStartKey
,以讀取該起點的下一個區塊。沒有LastEvaluatedKey
傳回該項目時, 表示沒有更多符合查詢或掃描的項目。
以下是一個簡單的範例 (使用 資源界面,但用戶端界面具有相同的模式),每個頁面和迴圈最多讀取 100 個項目,直到所有項目都已讀取為止。
import boto3 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']
為了方便起見,boto3 可以使用 Paginator 為您執行此操作。不過,它僅適用於用戶端界面。以下是改寫為使用 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)
如需詳細資訊,請參閱 Paginator 指南
注意
分頁器也有自己的組態設定,名為 MaxItems
、 StartingToken
和 PageSize
。若要使用 DynamoDB 分頁,您應該忽略這些設定。
等待程式
等待者提供在繼續之前等待完成項目的能力。目前,它們僅支援等待建立或刪除資料表。在背景中,等待程式操作會每 20 秒為您檢查一次,最多 25 次。您可以自行執行此操作,但在撰寫自動化時,使用等待器是很正常的。
此程式碼說明如何等待特定資料表建立完成:
# 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']