1.. dynamodb_v1_to_v2:
2
3=========================================
4Migrating from DynamoDB v1 to DynamoDB v2
5=========================================
6
7For the v2 release of AWS' DynamoDB_, the high-level API for interacting via
8``boto`` was rewritten. Since there were several new features added in v2,
9people using the v1 API may wish to transition their code to the new API.
10This guide covers the high-level APIs.
11
12.. _DynamoDB: http://aws.amazon.com/dynamodb/
13
14
15Creating New Tables
16===================
17
18DynamoDB v1::
19
20    >>> import boto.dynamodb
21    >>> conn = boto.dynamodb.connect_to_region()
22    >>> message_table_schema = conn.create_schema(
23    ...     hash_key_name='forum_name',
24    ...     hash_key_proto_value=str,
25    ...     range_key_name='subject',
26    ...     range_key_proto_value=str
27    ... )
28    >>> table = conn.create_table(
29    ...     name='messages',
30    ...     schema=message_table_schema,
31    ...     read_units=10,
32    ...     write_units=10
33    ... )
34
35DynamoDB v2::
36
37    >>> from boto.dynamodb2.fields import HashKey
38    >>> from boto.dynamodb2.fields import RangeKey
39    >>> from boto.dynamodb2.table import Table
40
41    >>> table = Table.create('messages', schema=[
42    ...     HashKey('forum_name'),
43    ...     RangeKey('subject'),
44    ... ], throughput={
45    ...     'read': 10,
46    ...     'write': 10,
47    ... })
48
49
50Using an Existing Table
51=======================
52
53DynamoDB v1::
54
55    >>> import boto.dynamodb
56    >>> conn = boto.dynamodb.connect_to_region()
57    # With API calls.
58    >>> table = conn.get_table('messages')
59
60    # Without API calls.
61    >>> message_table_schema = conn.create_schema(
62    ...     hash_key_name='forum_name',
63    ...     hash_key_proto_value=str,
64    ...     range_key_name='subject',
65    ...     range_key_proto_value=str
66    ... )
67    >>> table = conn.table_from_schema(
68    ...     name='messages',
69    ...     schema=message_table_schema)
70
71
72DynamoDB v2::
73
74    >>> from boto.dynamodb2.table import Table
75    # With API calls.
76    >>> table = Table('messages')
77
78    # Without API calls.
79    >>> from boto.dynamodb2.fields import HashKey
80    >>> from boto.dynamodb2.table import Table
81    >>> table = Table('messages', schema=[
82    ...     HashKey('forum_name'),
83    ...     HashKey('subject'),
84    ... ])
85
86
87Updating Throughput
88===================
89
90DynamoDB v1::
91
92    >>> import boto.dynamodb
93    >>> conn = boto.dynamodb.connect_to_region()
94    >>> table = conn.get_table('messages')
95    >>> conn.update_throughput(table, read_units=5, write_units=15)
96
97DynamoDB v2::
98
99    >>> from boto.dynamodb2.table import Table
100    >>> table = Table('messages')
101    >>> table.update(throughput={
102    ...     'read': 5,
103    ...     'write': 15,
104    ... })
105
106
107Deleting a Table
108================
109
110DynamoDB v1::
111
112    >>> import boto.dynamodb
113    >>> conn = boto.dynamodb.connect_to_region()
114    >>> table = conn.get_table('messages')
115    >>> conn.delete_table(table)
116
117DynamoDB v2::
118
119    >>> from boto.dynamodb2.table import Table
120    >>> table = Table('messages')
121    >>> table.delete()
122
123
124Creating an Item
125================
126
127DynamoDB v1::
128
129    >>> import boto.dynamodb
130    >>> conn = boto.dynamodb.connect_to_region()
131    >>> table = conn.get_table('messages')
132    >>> item_data = {
133    ...     'Body': 'http://url_to_lolcat.gif',
134    ...     'SentBy': 'User A',
135    ...     'ReceivedTime': '12/9/2011 11:36:03 PM',
136    ... }
137    >>> item = table.new_item(
138    ...     # Our hash key is 'forum'
139    ...     hash_key='LOLCat Forum',
140    ...     # Our range key is 'subject'
141    ...     range_key='Check this out!',
142    ...     # This has the
143    ...     attrs=item_data
144    ... )
145
146DynamoDB v2::
147
148    >>> from boto.dynamodb2.table import Table
149    >>> table = Table('messages')
150    >>> item = table.put_item(data={
151    ...     'forum_name': 'LOLCat Forum',
152    ...     'subject': 'Check this out!',
153    ...     'Body': 'http://url_to_lolcat.gif',
154    ...     'SentBy': 'User A',
155    ...     'ReceivedTime': '12/9/2011 11:36:03 PM',
156    ... })
157
158
159Getting an Existing Item
160========================
161
162DynamoDB v1::
163
164    >>> table = conn.get_table('messages')
165    >>> item = table.get_item(
166    ...     hash_key='LOLCat Forum',
167    ...     range_key='Check this out!'
168    ... )
169
170DynamoDB v2::
171
172    >>> table = Table('messages')
173    >>> item = table.get_item(
174    ...     forum_name='LOLCat Forum',
175    ...     subject='Check this out!'
176    ... )
177
178
179Updating an Item
180================
181
182DynamoDB v1::
183
184    >>> item['a_new_key'] = 'testing'
185    >>> del item['a_new_key']
186    >>> item.put()
187
188DynamoDB v2::
189
190    >>> item['a_new_key'] = 'testing'
191    >>> del item['a_new_key']
192
193    # Conditional save, only if data hasn't changed.
194    >>> item.save()
195
196    # Forced full overwrite.
197    >>> item.save(overwrite=True)
198
199    # Partial update (only changed fields).
200    >>> item.partial_save()
201
202
203Deleting an Item
204================
205
206DynamoDB v1::
207
208    >>> item.delete()
209
210DynamoDB v2::
211
212    >>> item.delete()
213
214
215Querying
216========
217
218DynamoDB v1::
219
220    >>> import boto.dynamodb
221    >>> conn = boto.dynamodb.connect_to_region()
222    >>> table = conn.get_table('messages')
223    >>> from boto.dynamodb.condition import BEGINS_WITH
224    >>> items = table.query('Amazon DynamoDB',
225    ...                     range_key_condition=BEGINS_WITH('DynamoDB'),
226    ...                     request_limit=1, max_results=1)
227    >>> for item in items:
228    >>>     print item['Body']
229
230DynamoDB v2::
231
232    >>> from boto.dynamodb2.table import Table
233    >>> table = Table('messages')
234    >>> items = table.query_2(
235    ...     forum_name__eq='Amazon DynamoDB',
236    ...     subject__beginswith='DynamoDB',
237    ...     limit=1
238    ... )
239    >>> for item in items:
240    >>>     print item['Body']
241
242
243Scans
244=====
245
246DynamoDB v1::
247
248    >>> import boto.dynamodb
249    >>> conn = boto.dynamodb.connect_to_region()
250    >>> table = conn.get_table('messages')
251
252    # All items.
253    >>> items = table.scan()
254
255    # With a filter.
256    >>> items = table.scan(scan_filter={'Replies': GT(0)})
257
258DynamoDB v2::
259
260    >>> from boto.dynamodb2.table import Table
261    >>> table = Table('messages')
262
263    # All items.
264    >>> items = table.scan()
265
266    # With a filter.
267    >>> items = table.scan(replies__gt=0)
268
269
270Batch Gets
271==========
272
273DynamoDB v1::
274
275    >>> import boto.dynamodb
276    >>> conn = boto.dynamodb.connect_to_region()
277    >>> table = conn.get_table('messages')
278    >>> from boto.dynamodb.batch import BatchList
279    >>> the_batch = BatchList(conn)
280    >>> the_batch.add_batch(table, keys=[
281    ...     ('LOLCat Forum', 'Check this out!'),
282    ...     ('LOLCat Forum', 'I can haz docs?'),
283    ...     ('LOLCat Forum', 'Maru'),
284    ... ])
285    >>> results = conn.batch_get_item(the_batch)
286
287    # (Largely) Raw dictionaries back from DynamoDB.
288    >>> for item_dict in response['Responses'][table.name]['Items']:
289    ...     print item_dict['Body']
290
291DynamoDB v2::
292
293    >>> from boto.dynamodb2.table import Table
294    >>> table = Table('messages')
295    >>> results = table.batch_get(keys=[
296    ...     {'forum_name': 'LOLCat Forum', 'subject': 'Check this out!'},
297    ...     {'forum_name': 'LOLCat Forum', 'subject': 'I can haz docs?'},
298    ...     {'forum_name': 'LOLCat Forum', 'subject': 'Maru'},
299    ... ])
300
301    # Lazy requests across pages, if paginated.
302    >>> for res in results:
303    ...     # You get back actual ``Item`` instances.
304    ...     print item['Body']
305
306
307Batch Writes
308============
309
310DynamoDB v1::
311
312    >>> import boto.dynamodb
313    >>> conn = boto.dynamodb.connect_to_region()
314    >>> table = conn.get_table('messages')
315    >>> from boto.dynamodb.batch import BatchWriteList
316    >>> from boto.dynamodb.item import Item
317
318    # You must manually manage this so that your total ``puts/deletes`` don't
319    # exceed 25.
320    >>> the_batch = BatchList(conn)
321    >>> the_batch.add_batch(table, puts=[
322    ...     Item(table, 'Corgi Fanciers', 'Sploots!', {
323    ...         'Body': 'Post your favorite corgi-on-the-floor shots!',
324    ...         'SentBy': 'User B',
325    ...         'ReceivedTime': '2013/05/02 10:56:45 AM',
326    ...     }),
327    ...     Item(table, 'Corgi Fanciers', 'Maximum FRAPS', {
328    ...         'Body': 'http://internetvideosite/watch?v=1247869',
329    ...         'SentBy': 'User C',
330    ...         'ReceivedTime': '2013/05/01 09:15:25 PM',
331    ...     }),
332    ... ], deletes=[
333    ...     ('LOLCat Forum', 'Off-topic post'),
334    ...     ('LOLCat Forum', 'They be stealin mah bukket!'),
335    ... ])
336    >>> conn.batch_write_item(the_writes)
337
338DynamoDB v2::
339
340    >>> from boto.dynamodb2.table import Table
341    >>> table = Table('messages')
342
343    # Uses a context manager, which also automatically handles batch sizes.
344    >>> with table.batch_write() as batch:
345    ...     batch.delete_item(
346    ...         forum_name='LOLCat Forum',
347    ...         subject='Off-topic post'
348    ...     )
349    ...     batch.put_item(data={
350    ...         'forum_name': 'Corgi Fanciers',
351    ...         'subject': 'Sploots!',
352    ...         'Body': 'Post your favorite corgi-on-the-floor shots!',
353    ...         'SentBy': 'User B',
354    ...         'ReceivedTime': '2013/05/02 10:56:45 AM',
355    ...     })
356    ...     batch.put_item(data={
357    ...         'forum_name': 'Corgi Fanciers',
358    ...         'subject': 'Sploots!',
359    ...         'Body': 'Post your favorite corgi-on-the-floor shots!',
360    ...         'SentBy': 'User B',
361    ...         'ReceivedTime': '2013/05/02 10:56:45 AM',
362    ...     })
363    ...     batch.delete_item(
364    ...         forum_name='LOLCat Forum',
365    ...         subject='They be stealin mah bukket!'
366    ...     )
367