I have some existing code that uses boto3 (python) DynamoDB Table objects to query the database:
import boto3
resource = boto3.resource("dynamodb")
table = resource.table("my_table")
# Do stuff here
We now want to run the tests for this code using DynamoDB Local instead of connecting to DynamoDB proper, to try and get them running faster and save on resources. To do that, I gather that I need to use a client object, not a table object:
import boto3
session = boto3.session.Session()
db_client = session.client(service_name="dynamodb", endpoint_url="http://localhost:8000")
# Do slightly different stuff here, 'cos clients and tables work differently
However, there’s really rather a lot of the existing code, to the point that the cost of rewriting everything to work with clients rather than tables is likely to be prohibitive.
Is there any way to either get a table object while specifying the endpoint_url so I can point it at DynamoDB Local on creation, or else obtain a boto3 dynamodb table object from a boto3 dynamodb client object?
PS: I know I could also mock out the boto3 calls and not access the database at all. But that’s also prohibitively costly, because for all of the existing tests we’d have to work out where they touch the database and what the appropriate mock setup and use is. For a couple of tests that’s perfectly fine, but it’s a lot of work if you’ve got a lot of tests.
2
Answers
Yes, you can use the resource-level classes such as Table with both the real DynamoDB service and DynamoDB Local via the DynamoDB service resource, as follows:
The other answers correctly told you that if you liked the "resource" API, you can still use it even with DynamoDB local (by the way, shameless plug: if you’re looking for self-installable version of DynamoDB, you can also consider the open-source ScyllaDB project which has a DynamoDB API).
I just wanted to add that if you do want to switch to the "client" API – which I recommend (it’s easier to use) – it’s still possible to get a table object from a client. Just do: