【问题标题】:How to check if DynamoDB table exists?如何检查 DynamoDB 表是否存在?
【发布时间】:2017-07-18 01:24:09
【问题描述】:

我是 boto3 的新用户,我正在使用 DynamoDB

我浏览了 DynamoDB api,但找不到任何方法可以告诉我表是否已经存在。

处理此问题的最佳方法是什么?

我应该尝试创建一个新表并使用 try catch 包装它吗?

【问题讨论】:

  • 使用dynamodb-data-mapper check提供函数ensureTableExists,如果不存在则创建表

标签: python amazon-dynamodb boto3


【解决方案1】:

通过阅读文档,我可以看到有三种方法可以检查表是否存在。

  1. 如果表已经存在,CreateTable API 会抛出错误ResourceInUseException。用 try 包裹 create_table 方法来捕获它
  2. 您可以使用ListTables API 获取与当前帐户和端点关联的表名列表。检查您在响应中获得的表名列表中是否存在该表名。
  3. 如果您请求的表名不存在,DescribeTable API 将抛出错误ResourceNotFoundException

对我来说,如果您只想创建一个表,第一个选项听起来更好。

编辑: 我看到有些人发现很难捕捉到异常。我会在下面放一些代码让你知道如何处理boto3中的异常。

示例 1

import boto3

dynamodb_client = boto3.client('dynamodb')

try:
    response = dynamodb_client.create_table(
        AttributeDefinitions=[
            {
                'AttributeName': 'Artist',
                'AttributeType': 'S',
            },
            {
                'AttributeName': 'SongTitle',
                'AttributeType': 'S',
            },
        ],
        KeySchema=[
            {
                'AttributeName': 'Artist',
                'KeyType': 'HASH',
            },
            {
                'AttributeName': 'SongTitle',
                'KeyType': 'RANGE',
            },
        ],
        ProvisionedThroughput={
            'ReadCapacityUnits': 5,
            'WriteCapacityUnits': 5,
        },
        TableName='test',
    )
except dynamodb_client.exceptions.ResourceInUseException:
    # do something here as you require
    pass

示例 2

import boto3

dynamodb_client = boto3.client('dynamodb')


table_name = 'test'
existing_tables = dynamodb_client.list_tables()['TableNames']

if table_name not in existing_tables:
    response = dynamodb_client.create_table(
        AttributeDefinitions=[
            {
                'AttributeName': 'Artist',
                'AttributeType': 'S',
            },
            {
                'AttributeName': 'SongTitle',
                'AttributeType': 'S',
            },
        ],
        KeySchema=[
            {
                'AttributeName': 'Artist',
                'KeyType': 'HASH',
            },
            {
                'AttributeName': 'SongTitle',
                'KeyType': 'RANGE',
            },
        ],
        ProvisionedThroughput={
            'ReadCapacityUnits': 5,
            'WriteCapacityUnits': 5,
        },
        TableName=table_name,
    )

示例 3

import boto3

dynamodb_client = boto3.client('dynamodb')

try:
    response = dynamodb_client.describe_table(TableName='test')
except dynamodb_client.exceptions.ResourceNotFoundException:
    # do something here as you require
    pass

【讨论】:

  • describe_table 我得到AttributeError: 'dynamodb.ServiceResource' object has no attribute 'describe_table'
  • 那是因为你使用的是服务资源而不是客户端。检查代码中的这一行:dynamodb_client = boto3.client('dynamodb')
  • 示例 3 很棒,但我得到了一个 ClientError 抛出:``` dynamodb = boto3.resource(self._dynamodb_resource_name, region_name=self._region, endpoint_url=self._endpoint_url) # 尝试删除表,如果不存在则忽略 table = dynamodb.Table(self._tableName) try: table.delete() except ClientError as e: if e.response['Error']['Code'] != 'ResourceNotFoundException':提高 e ```
  • 代码看起来不像我上面发布的。你从哪里得到代码?它对你有用吗?ClientError 是从哪里导入的?
  • 所描述的异常处理将与客户端 API 一起使用,但是无论如何可以从资源 API 中捕获异常?例如 boto3.resource("dynamodb").Table("table_that_doesnt_exist") 会引发 ResourceNotFoundException 但我无法使用此用例进行捕获。
【解决方案2】:
import boto3

from botocore.exceptions import ClientError

TABLE_NAME = "myTableName"
dynamodb = boto3.resource('dynamodb', endpoint_url="https://dynamodb.us-east-1.amazonaws.com")

table = dynamodb.Table(TABLE_NAME)

try:
    response = client.describe_table(TableName=TABLE_NAME)

except ClientError as ce:
if ce.response['Error']['Code'] == 'ResourceNotFoundException':
    print "Table " + TABLE_NAME + " does not exist. Create the table first and try again."
else:
    print "Unknown exception occurred while querying for the " + TABLE_NAME + " table. Printing full error:"
    pprint.pprint(ce.response)

【讨论】:

  • 谢谢你!我正在失去我剩下的头发。
  • 这是我 3 年前写的。尝试从dynamodb 对象中获取client 对象。这是我目前最好的猜测。
【解决方案3】:

如果您不想使用boto3.client 而只想使用boto3.resource,则另一种方法:

import boto3

database = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")    

table_name  = 'MyTable'
table_names = [table.name for table in database.tables.all()]

if table_name in table_names:
    print('table', table_name, 'exists')

【讨论】:

    【解决方案4】:

    您可以使用describe table API 来判断该表是否存在。

    示例代码:

    from __future__ import print_function # Python 2/3 compatibility
    import os
    os.environ["TZ"] = "UTC"
    import boto3
    
    client = boto3.client('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000")
    
    
    
    response = client.describe_table(
        TableName='Movies'
    )    
    
    print(response)
    

    如果表存在:-

    • 您会收到回复

    如果表不存在:-

    • 你会得到ResourceNotFoundException

      botocore.errorfactory.ResourceNotFoundException:发生错误(ResourceNotF oudException) 调用 DescribeTable 操作时:无法对 一个不存在的表

    另一种方式:-

    等到此表存在。该方法调用 轮询的 DynamoDB.Waiter.table_exists.wait()。 DynamoDB.Client.describe_table() 每 20 秒一次,直到成功 状态达到。检查失败 25 次后返回错误。

    table.wait_until_exists()
    

    【讨论】:

    • 我喜欢你的代码,但不知道如何导入botocore.errorfactory.ResourceNotFoundException。我不断收到AttributeError: 'module' object has no attribute 'ResourceNotFoundException'。我导入了boto3botocore
    • @anon58192932 您知道如何导入该异常吗?我也面临同样的问题。
    • @Phito 很抱歉耽搁了我刚回到工作岗位。请参阅我将发布的关于如何检查异常的答案。据我了解,不能直接导入。
    • @Phito:我已经编辑了我的答案以包含有关如何在 boto3 中捕获异常的示例代码。
    • @anupsabraham 我没有找到捕获异常的确切语法,所以在这里发布一个示例_cwevents_client: BaseClient = _master_session.client('events', region_name=aws_region) try: _cwevents_client.describe_rule(Name=ruleName) logger.info("Determined that guarddutyAlert rule already exists") except _cwevents_client.exceptions.ResourceNotFoundException: logger.info("Creating the guarddutyAlert CloudWatch rule")
    【解决方案5】:

    您可以使用任何 boto3 Table 实例对象的.table_status attr。如果存在(CREATING、UPDATING、DELETING、ACTIVE)或抛出异常botocore.exceptions.ClientError: Requested resource not found: Table: <YOUR_TABLE_NAME> not found,它将返回其状态。您可以将这些条件包装到 try / 中,以获取有关当前表状态的完整信息。

    import boto3
    from botocore.exceptions import ClientError
    
    dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
    table = dynamodb.Table('your_table_name_str')
    
    try:
      is_table_existing = table.table_status in ("CREATING", "UPDATING",
                                                 "DELETING", "ACTIVE")
    except ClientError:
      is_table_existing = False
      print "Table %s doesn't exist." % table.name
    

    【讨论】:

      【解决方案6】:

      请注意,这取决于您使用的是客户端还是资源。如果您使用boto3.client(),则可以使用接受的答案建议的 3 种方法。如果您使用boto3.resource(),则只能使用dynamodb_resource.create_table()并检查异常。

      try:
          table = dynamodb_resource.create_table(
              ...
          )
          table.meta.client.get_waiter('table_exists').wait(TableName=your_table_name)
      except ResourceInUseException:
          # do sth here
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-29
        • 2019-11-25
        • 2013-04-07
        • 1970-01-01
        相关资源
        最近更新 更多