################################## Getting started with DynamoDB-Mock ################################## .. include:: ../_include/intro.rst Installation ============ :: $ pip install ddbmock Example usage ============= Run as Regular client-server ---------------------------- Ideal for test environment. For stage and production I highly recommend using DynamoDB servers. ddbmock comes with no warranty and *will* **loose your data(tm)**. Launch the server :: $ pserve development.ini # launch the server on 0.0.0.0:6543 Start the client :: import boto from ddbmock import connect_boto_network # Use the provided helper to connect your *own* endpoint db = connect_boto_network() # Done ! just use it wherever in your project as usual. db.list_tables() # get list of tables (empty at this stage) Note: if you do not want to import ddbmock only for the helper, here is a reference implementation: :: def connect_boto_network(host='localhost', port=6543): import boto from boto.regioninfo import RegionInfo endpoint = '{}:{}'.format(host, port) region = RegionInfo(name='ddbmock', endpoint=endpoint) return boto.connect_dynamodb(region=region, port=port, is_secure=False) Run as a standalone library --------------------------- Ideal for unit testing or small scale automated functional tests. Nice to play around with boto DynamoDB API too :) :: import boto from ddbmock import connect_boto_patch # Wire-up boto and ddbmock together db = connect_boto_patch() # Done ! just use it wherever in your project as usual. db.list_tables() # get list of tables (empty at this stage) Note, to clean patches made in ``boto.dynamodb.layer1``, you can call ``clean_boto_patch()`` from the same module. Using ddbmock for tests ======================= Most tests share the same structure: 1. Set the things up 2. Test and validate 3. Clean everything up and start again If you use ``ddbmock`` as a standalone library (which I recommend for this purpose), feel free to access any of the public methods in the ``database`` and ``table`` to perform direct checks Here is a template taken from ``GetItem`` functional test using Boto. :: # -*- coding: utf-8 -*- import unittest import boto TABLE_NAME = 'Table-HR' TABLE_RT = 45 TABLE_WT = 123 TABLE_HK_NAME = u'hash_key' TABLE_HK_TYPE = u'N' TABLE_RK_NAME = u'range_key' TABLE_RK_TYPE = u'S' HK_VALUE = u'123' RK_VALUE = u'Decode this data if you are a coder' ITEM = { TABLE_HK_NAME: {TABLE_HK_TYPE: HK_VALUE}, TABLE_RK_NAME: {TABLE_RK_TYPE: RK_VALUE}, u'relevant_data': {u'B': u'THVkaWEgaXMgdGhlIGJlc3QgY29tcGFueSBldmVyIQ=='}, } class TestGetItem(unittest.TestCase): def setUp(self): from ddbmock.database.db import dynamodb from ddbmock.database.table import Table from ddbmock.database.key import PrimaryKey # Do a full database wipe dynamodb.hard_reset() # Instanciate the keys hash_key = PrimaryKey(TABLE_HK_NAME, TABLE_HK_TYPE) range_key = PrimaryKey(TABLE_RK_NAME, TABLE_RK_TYPE) # Create a test table and register it in ``self`` so that you can use it directly self.t1 = Table(TABLE_NAME, TABLE_RT, TABLE_WT, hash_key, range_key) # Very important: register the table in the DB dynamodb.data[TABLE_NAME] = self.t1 # Unconditionally add some data, for example. self.t1.put(ITEM, {}) def tearDown(self): from ddbmock.database.db import dynamodb from ddbmock import clean_boto_patch # Do a full database wipe dynamodb.hard_reset() # Remove the patch from Boto code (if any) clean_boto_patch() def test_get_hr(self): from ddbmock import connect_boto_patch from ddbmock.database.db import dynamodb # Create the database connection ie: patch boto db = connect_boto_patch() # Example test expected = { u'ConsumedCapacityUnits': 0.5, u'Item': ITEM, } key = { u"HashKeyElement": {TABLE_HK_TYPE: HK_VALUE}, u"RangeKeyElement": {TABLE_RK_TYPE: RK_VALUE}, } # Example chech self.assertEquals(expected, db.layer1.get_item(TABLE_NAME, key)) If ddbmock is used as a standalone server, restarting it should do the job, unless SQLite persistence is used. Advanced usage ============== A significant part of ddbmock is now configurable through ``ddbmock.config`` parameters. This includes the storage backend. By default, ddbmock has no persitence and stores everything in-memory. Alternatively, you can use the ``SQLite`` storage engine but be warned that it will be slower. To switch the backend, you will to change a configuration variable *before* creating the first table. :: from ddbmock import config # switch to sqlite backend config.STORAGE_ENGINE_NAME = 'sqlite' # define the database path. defaults to 'dynamo.db' config.STORAGE_SQLITE_FILE = '/tmp/my_database.sqlite' Please note that ddbmock does not persist table metadata currently. As a consequence, you will need to create the tables at each restart even with the SQLite backend. This is hoped to be improved in future releases. See https://bitbucket.org/Ludia/dynamodb-mock/src/tip/ddbmock/config.py for a full list of parameters.