def test_local_index(self): """Can query on a local index""" hash_key = DynamoKey("id", data_type=STRING) range_key = DynamoKey("num", data_type=NUMBER) index_field = DynamoKey("name") index = LocalIndex.keys("name-index", index_field) self.dynamo.create_table("foobar", hash_key, range_key, indexes=[index]) item = { "id": "a", "num": 1, "name": "baz", } self.dynamo.put_item("foobar", item) ret = self.dynamo.query( "foobar", "id = :id and #name = :name", alias={"#name": "name"}, index="name-index", id="a", name="baz", ) self.assertCountEqual(list(ret), [item])
def _create(self, tree): """ Run a SELECT statement """ tablename = tree.table indexes = [] global_indexes = [] hash_key = None range_key = None attrs = {} for declaration in tree.attrs: name, type_ = declaration[:2] if len(declaration) > 2: index = declaration[2] else: index = None if index is not None: if index[0] == "HASH": field = hash_key = DynamoKey(name, data_type=TYPES[type_]) elif index[0] == "RANGE": field = range_key = DynamoKey(name, data_type=TYPES[type_]) else: index_type = index[0] kwargs = {} if index_type[0] in ("ALL", "INDEX"): factory = LocalIndex.all elif index_type[0] == "KEYS": factory = LocalIndex.keys elif index_type[0] == "INCLUDE": factory = LocalIndex.include kwargs["includes"] = [ resolve(v) for v in index.include_vars ] index_name = resolve(index[1]) field = DynamoKey(name, data_type=TYPES[type_]) idx = factory(index_name, field, **kwargs) indexes.append(idx) else: field = DynamoKey(name, data_type=TYPES[type_]) attrs[field.name] = field for gindex in tree.global_indexes: global_indexes.append(self._parse_global_index(gindex, attrs)) throughput = None if tree.throughput: throughput = Throughput(*map(resolve, tree.throughput)) try: ret = self.connection.create_table( tablename, hash_key, range_key, indexes=indexes, global_indexes=global_indexes, throughput=throughput, ) except DynamoDBError as e: if e.kwargs["Code"] == "ResourceInUseException" or tree.not_exists: return False raise return True
def make_table(self): """Convenience method for making a table""" hash_key = DynamoKey("id") range_key = DynamoKey("num", data_type=NUMBER) self.dynamo.create_table("foobar", hash_key=hash_key, range_key=range_key)
def test_create_hash_range_table(self): """ Create a table with a hash and range key """ hash_key = DynamoKey('id', data_type=STRING) range_key = DynamoKey('num', data_type=NUMBER) table = Table('foobar', hash_key, range_key) self.dynamo.create_table('foobar', hash_key, range_key) desc = self.dynamo.describe_table('foobar') self.assertEqual(desc, table)
def test_create_global_keys_index(self): """ Create a table with a global KeysOnly index """ hash_key = DynamoKey('id', data_type=STRING) index_field = DynamoKey('name') index = GlobalIndex.keys('name-index', index_field) table = Table('foobar', hash_key, global_indexes=[index]) self.dynamo.create_table('foobar', hash_key, global_indexes=[index]) desc = self.dynamo.describe_table('foobar') self.assertEqual(desc, table)
def test_create_global_index(self): """Create a table with a global index""" hash_key = DynamoKey("id", data_type=STRING) index_field = DynamoKey("name") index = GlobalIndex.all("name-index", index_field) table = Table("foobar", hash_key, global_indexes=[index]) self.dynamo.create_table("foobar", hash_key, global_indexes=[index]) desc = self.dynamo.describe_table("foobar") self.assertEqual(desc, table)
def test_create_global_hash_range_index(self): """ Create a global index with a hash and range key """ hash_key = DynamoKey('id', data_type=STRING) index_hash = DynamoKey('foo') index_range = DynamoKey('bar') index = GlobalIndex.all('foo-index', index_hash, index_range) table = Table('foobar', hash_key, global_indexes=[index]) self.dynamo.create_table('foobar', hash_key, global_indexes=[index]) desc = self.dynamo.describe_table('foobar') self.assertEqual(desc, table)
def test_create_local_includes_index(self): """Create a table with a local Includes index""" hash_key = DynamoKey("id", data_type=STRING) range_key = DynamoKey("num", data_type=NUMBER) index_field = DynamoKey("name") index = LocalIndex.include("name-index", index_field, includes=["foo", "bar"]) table = Table("foobar", hash_key, range_key, [index]) self.dynamo.create_table("foobar", hash_key, range_key, indexes=[index]) desc = self.dynamo.describe_table("foobar") self.assertEqual(desc, table)
def test_create_index(self): """Create a global index""" hash_key = DynamoKey("id", data_type=STRING) self.dynamo.create_table("foobar", hash_key=hash_key) index_field = DynamoKey("name") index = GlobalIndex.all("name-index", index_field, hash_key) self.dynamo.update_table("foobar", index_updates=[IndexUpdate.create(index)]) table = self.dynamo.describe_table("foobar") assert table is not None self.assertEqual(len(table.global_indexes), 1)
def test_create_index(self): """ Create a global index """ hash_key = DynamoKey('id', data_type=STRING) self.dynamo.create_table('foobar', hash_key=hash_key) index_field = DynamoKey('name') index = GlobalIndex.all('name-index', index_field, hash_key) self.dynamo.update_table('foobar', index_updates=[IndexUpdate.create(index)]) table = self.dynamo.describe_table('foobar') self.assertEqual(len(table.global_indexes), 1)
def test_beginswith(self): """ Can query with 'begins with' constraint """ hash_key = DynamoKey('id') range_key = DynamoKey('name') self.dynamo.create_table('foobar', hash_key=hash_key, range_key=range_key) item = {'id': 'a', 'name': 'David'} self.dynamo.put_item('foobar', {'id': 'a', 'name': 'Steven'}) self.dynamo.put_item('foobar', item) ret = self.dynamo.query('foobar', id__eq='a', name__beginswith='D') self.assertItemsEqual(list(ret), [item])
def test_update_global_index_throughput_old(self): """ Update throughput on a global index OLD API """ hash_key = DynamoKey('id', data_type=STRING) index_field = DynamoKey('name') index = GlobalIndex.all('name-index', index_field) self.dynamo.create_table('foobar', hash_key=hash_key, global_indexes=[index]) tp = Throughput(2, 1) self.dynamo.update_table('foobar', global_indexes={'name-index': tp}) table = self.dynamo.describe_table('foobar') self.assertEqual(table.global_indexes[0].throughput, tp)
def test_create_global_index_throughput(self): """Create a table and set throughput on global index""" hash_key = DynamoKey("id", data_type=STRING) throughput = Throughput(8, 2) index_field = DynamoKey("name") index = GlobalIndex.all("name-index", index_field, throughput=throughput) table = Table("foobar", hash_key, global_indexes=[index], throughput=throughput) self.dynamo.create_table( "foobar", hash_key=hash_key, global_indexes=[index], throughput=throughput ) desc = self.dynamo.describe_table("foobar") self.assertEqual(desc, table)
def test_create_local_index(self): """ Create a table with a local index """ hash_key = DynamoKey('id', data_type=STRING) range_key = DynamoKey('num', data_type=NUMBER) index_field = DynamoKey('name') index = LocalIndex.all('name-index', index_field) table = Table('foobar', hash_key, range_key, [index]) self.dynamo.create_table('foobar', hash_key, range_key, indexes=[index]) desc = self.dynamo.describe_table('foobar') self.assertEqual(desc, table)
def test_update_index_throughput(self): """Update the throughput on a global index""" hash_key = DynamoKey("id", data_type=STRING) index_field = DynamoKey("name") index = GlobalIndex.all("name-index", index_field) self.dynamo.create_table("foobar", hash_key=hash_key, global_indexes=[index]) tp = Throughput(2, 1) self.dynamo.update_table( "foobar", index_updates=[IndexUpdate.update("name-index", tp)] ) table = self.dynamo.describe_table("foobar") assert table is not None self.assertEqual(table.global_indexes[0].throughput, tp)
def get_ddb_index(self, fields): """ Get the dynamo index class for this GlobalIndex """ hash_key = DynamoKey(self.hash_key, data_type=fields[self.hash_key].ddb_data_type) range_key = None if self.range_key is not None: range_key = DynamoKey( self.range_key, data_type=fields[self.range_key].ddb_data_type) index = self.ddb_index(self.name, hash_key, range_key, throughput=self._throughput, **self.kwargs) return index
def test_delete_index(self): """ Delete a global index """ hash_key = DynamoKey('id', data_type=STRING) index_field = DynamoKey('name') index = GlobalIndex.all('name-index', index_field) self.dynamo.create_table('foobar', hash_key=hash_key, global_indexes=[index]) self.dynamo.update_table( 'foobar', index_updates=[IndexUpdate.delete('name-index')]) table = self.dynamo.describe_table('foobar') self.assertTrue( len(table.global_indexes) == 0 or table.global_indexes[0].index_status == 'DELETING')
def test_delete_index(self): """Delete a global index""" hash_key = DynamoKey("id", data_type=STRING) index_field = DynamoKey("name") index = GlobalIndex.all("name-index", index_field) self.dynamo.create_table("foobar", hash_key=hash_key, global_indexes=[index]) self.dynamo.update_table( "foobar", index_updates=[IndexUpdate.delete("name-index")] ) table = self.dynamo.describe_table("foobar") assert table is not None self.assertTrue( len(table.global_indexes) == 0 or table.global_indexes[0].status == "DELETING" )
def test_global_index(self): """ Can query on a global index """ hash_key = DynamoKey('id', data_type=STRING) index_field = DynamoKey('name') index = GlobalIndex.all('name-index', index_field) self.dynamo.create_table('foobar', hash_key, global_indexes=[index]) item = { 'id': 'a', 'name': 'baz', } self.dynamo.put_item('foobar', item) ret = self.dynamo.query('foobar', name__eq='baz', index='name-index', filter={'id__eq': 'a'}) self.assertItemsEqual(list(ret), [item])
def test_table_eq(self): """Tables should be equal""" field = DynamoKey("foo") a, b = Table("a", field), Table("a", field) self.assertEqual(a, b) self.assertEqual(hash(a), hash(b)) self.assertFalse(a != b)
def test_global_index_eq(self): """Global indexes should be equal""" hash_key = DynamoKey("foo") a, b = GlobalIndex.all("a", hash_key), GlobalIndex.all("a", hash_key) self.assertEqual(a, b) self.assertEqual(hash(a), hash(b)) self.assertFalse(a != b)
def test_local_index_eq(self): """Local indexes should be equal""" range_key = DynamoKey("foo") a, b = LocalIndex.all("a", range_key), LocalIndex.all("a", range_key) self.assertEqual(a, b) self.assertEqual(hash(a), hash(b)) self.assertFalse(a != b)
def test_list_tables_page(self): """ Call to ListTables should page results """ hash_key = DynamoKey('id') for i in range(120): self.dynamo.create_table('table%d' % i, hash_key=hash_key) tables = list(self.dynamo.list_tables(110)) self.assertEqual(len(tables), 110)
def test_magic_index_props(self): """ Index magically looks up properties on response object """ index = GlobalIndex.all('idx-name', DynamoKey('id')) index.response = {'FooBar': 2} self.assertEqual(index.foo_bar, 2) with self.assertRaises(AttributeError): self.assertIsNotNone(index.crazy_property)
def test_wait_delete_table(self): """ Delete table shall wait for the table to go offline. """ tablename = 'foobar_wait' hash_key = DynamoKey('id') self.dynamo.create_table(tablename, hash_key=hash_key, wait=True) result = self.dynamo.delete_table(tablename, wait=True) self.assertTrue(result)
def test_hash(self): """ Can query on the hash key """ hash_key = DynamoKey('id') self.dynamo.create_table('foobar', hash_key) self.dynamo.put_item('foobar', {'id': 'a'}) results = self.dynamo.query2('foobar', 'id = :id', id='a') self.assertItemsEqual(list(results), [{'id': 'a'}])
def test_create_hash_table(self): """ Create a table with just a hash key """ hash_key = DynamoKey('id', data_type=STRING) table = Table('foobar', hash_key) self.dynamo.create_table('foobar', hash_key=hash_key) desc = self.dynamo.describe_table('foobar') self.assertEqual(desc, table)
def make_table(self, items=10): """ Convenience method for making a table """ hash_key = DynamoKey('id') self.dynamo.create_table('foobar', hash_key=hash_key) with self.dynamo.batch_write('foobar') as batch: for i in range(items): batch.put({'id': str(i), 'num': i})
def test_attributes(self): """Can limit fetch to specific attributes""" hash_key = DynamoKey("id") self.dynamo.create_table("foobar", hash_key=hash_key) self.dynamo.put_item("foobar", {"id": "a", "foo": "bar"}) ret = self.dynamo.txn_get("foobar", [{"id": "a"}], attributes=["id"]) self.assertCountEqual(ret, [{"id": "a"}])
def make_table(self, items=10): """Convenience method for making a table""" hash_key = DynamoKey("id") self.dynamo.create_table("foobar", hash_key=hash_key) with self.dynamo.batch_write("foobar") as batch: for i in range(items): batch.put({"id": str(i), "num": i})