| OLD | NEW |
| (Empty) | |
| 1 .. dynamodb_tut: |
| 2 |
| 3 ============================================ |
| 4 An Introduction to boto's DynamoDB interface |
| 5 ============================================ |
| 6 |
| 7 This tutorial focuses on the boto interface to AWS' DynamoDB_. This tutorial |
| 8 assumes that you have boto already downloaded and installed. |
| 9 |
| 10 .. _DynamoDB: http://aws.amazon.com/dynamodb/ |
| 11 |
| 12 Creating a Connection |
| 13 --------------------- |
| 14 |
| 15 The first step in accessing DynamoDB is to create a connection to the service. |
| 16 To do so, the most straight forward way is the following:: |
| 17 |
| 18 >>> import boto |
| 19 >>> conn = boto.connect_dynamodb( |
| 20 aws_access_key_id='<YOUR_AWS_KEY_ID>', |
| 21 aws_secret_access_key='<YOUR_AWS_SECRET_KEY>') |
| 22 >>> conn |
| 23 <boto.dynamodb.layer2.Layer2 object at 0x3fb3090> |
| 24 |
| 25 Bear in mind that if you have your credentials in boto config in your home |
| 26 directory, the two keyword arguments in the call above are not needed. More |
| 27 details on configuration can be found in :doc:`boto_config_tut`. |
| 28 |
| 29 .. note:: At this |
| 30 time, Amazon DynamoDB is available only in the US-EAST-1 region. The |
| 31 ``connect_dynamodb`` method automatically connect to that region. |
| 32 |
| 33 The :py:func:`boto.connect_dynamodb` functions returns a |
| 34 :py:class:`boto.dynamodb.layer2.Layer2` instance, which is a high-level API |
| 35 for working with DynamoDB. Layer2 is a set of abstractions that sit atop |
| 36 the lower level :py:class:`boto.dynamodb.layer1.Layer1` API, which closely |
| 37 mirrors the Amazon DynamoDB API. For the purpose of this tutorial, we'll |
| 38 just be covering Layer2. |
| 39 |
| 40 Listing Tables |
| 41 -------------- |
| 42 |
| 43 Now that we have a DynamoDB connection object, we can then query for a list of |
| 44 existing tables in that region:: |
| 45 |
| 46 >>> conn.list_tables() |
| 47 ['test-table', 'another-table'] |
| 48 |
| 49 Creating Tables |
| 50 --------------- |
| 51 |
| 52 DynamoDB tables are created with the |
| 53 :py:meth:`Layer2.create_table <boto.dynamodb.layer2.Layer2.create_table>` |
| 54 method. While DynamoDB's items (a rough equivalent to a relational DB's row) |
| 55 don't have a fixed schema, you do need to create a schema for the table's |
| 56 hash key element, and the optional range key element. This is explained in |
| 57 greater detail in DynamoDB's `Data Model`_ documentation. |
| 58 |
| 59 We'll start by defining a schema that has a hash key and a range key that |
| 60 are both keys:: |
| 61 |
| 62 >>> message_table_schema = conn.create_schema( |
| 63 hash_key_name='forum_name', |
| 64 hash_key_proto_value='S', |
| 65 range_key_name='subject', |
| 66 range_key_proto_value='S' |
| 67 ) |
| 68 |
| 69 The next few things to determine are table name and read/write throughput. We'll |
| 70 defer explaining throughput to the DynamoDB's `Provisioned Throughput`_ docs. |
| 71 |
| 72 We're now ready to create the table:: |
| 73 |
| 74 >>> table = conn.create_table( |
| 75 name='messages', |
| 76 schema=message_table_schema, |
| 77 read_units=10, |
| 78 write_units=10 |
| 79 ) |
| 80 >>> table |
| 81 Table(messages) |
| 82 |
| 83 This returns a :py:class:`boto.dynamodb.table.Table` instance, which provides |
| 84 simple ways to create (put), update, and delete items. |
| 85 |
| 86 .. _Data Model: http://docs.amazonwebservices.com/amazondynamodb/latest/develope
rguide/DataModel.html |
| 87 .. _Provisioned Throughput: http://docs.amazonwebservices.com/amazondynamodb/lat
est/developerguide/ProvisionedThroughputIntro.html |
| 88 |
| 89 Getting a Table |
| 90 --------------- |
| 91 |
| 92 To retrieve an existing table, use |
| 93 :py:meth:`Layer2.get_table <boto.dynamodb.layer2.Layer2.get_table>`:: |
| 94 |
| 95 >>> conn.list_tables() |
| 96 ['test-table', 'another-table', 'messages'] |
| 97 >>> table = conn.get_table('messages') |
| 98 >>> table |
| 99 Table(messages) |
| 100 |
| 101 :py:meth:`Layer2.get_table <boto.dynamodb.layer2.Layer2.get_table>`, like |
| 102 :py:meth:`Layer2.create_table <boto.dynamodb.layer2.Layer2.create_table>`, |
| 103 returns a :py:class:`boto.dynamodb.table.Table` instance. |
| 104 |
| 105 Describing Tables |
| 106 ----------------- |
| 107 |
| 108 To get a complete description of a table, use |
| 109 :py:meth:`Layer2.describe_table <boto.dynamodb.layer2.Layer2.describe_table>`:: |
| 110 |
| 111 >>> conn.list_tables() |
| 112 ['test-table', 'another-table', 'messages'] |
| 113 >>> conn.describe_table('messages') |
| 114 { |
| 115 'Table': { |
| 116 'CreationDateTime': 1327117581.624, |
| 117 'ItemCount': 0, |
| 118 'KeySchema': { |
| 119 'HashKeyElement': { |
| 120 'AttributeName': 'forum_name', |
| 121 'AttributeType': 'S' |
| 122 }, |
| 123 'RangeKeyElement': { |
| 124 'AttributeName': 'subject', |
| 125 'AttributeType': 'S' |
| 126 } |
| 127 }, |
| 128 'ProvisionedThroughput': { |
| 129 'ReadCapacityUnits': 10, |
| 130 'WriteCapacityUnits': 10 |
| 131 }, |
| 132 'TableName': 'messages', |
| 133 'TableSizeBytes': 0, |
| 134 'TableStatus': 'ACTIVE' |
| 135 } |
| 136 } |
| 137 |
| 138 Adding Items |
| 139 ------------ |
| 140 |
| 141 Continuing on with our previously created ``messages`` table, adding an:: |
| 142 |
| 143 >>> table = conn.get_table('messages') |
| 144 >>> item_data = { |
| 145 'Body': 'http://url_to_lolcat.gif', |
| 146 'SentBy': 'User A', |
| 147 'ReceivedTime': '12/9/2011 11:36:03 PM', |
| 148 } |
| 149 >>> item = table.new_item( |
| 150 # Our hash key is 'forum' |
| 151 hash_key='LOLCat Forum', |
| 152 # Our range key is 'subject' |
| 153 range_key='Check this out!', |
| 154 # This has the |
| 155 attrs=item_data |
| 156 ) |
| 157 |
| 158 The |
| 159 :py:meth:`Table.new_item <boto.dynamodb.table.Table.new_item>` method creates |
| 160 a new :py:class:`boto.dynamodb.item.Item` instance with your specified |
| 161 hash key, range key, and attributes already set. |
| 162 :py:class:`Item <boto.dynamodb.item.Item>` is a :py:class:`dict` sub-class, |
| 163 meaning you can edit your data as such:: |
| 164 |
| 165 item['a_new_key'] = 'testing' |
| 166 del item['a_new_key'] |
| 167 |
| 168 After you are happy with the contents of the item, use |
| 169 :py:meth:`Item.put <boto.dynamodb.item.Item.put>` to commit it to DynamoDB:: |
| 170 |
| 171 >>> item.put() |
| 172 |
| 173 Retrieving Items |
| 174 ---------------- |
| 175 |
| 176 Now, let's check if it got added correctly. Since DynamoDB works under an |
| 177 'eventual consistency' mode, we need to specify that we wish a consistent read, |
| 178 as follows:: |
| 179 |
| 180 >>> table = conn.get_table('messages') |
| 181 >>> item = table.get_item( |
| 182 # Your hash key was 'forum_name' |
| 183 hash_key='LOLCat Forum', |
| 184 # Your range key was 'subject' |
| 185 range_key='Check this out!' |
| 186 ) |
| 187 >>> item |
| 188 { |
| 189 # Note that this was your hash key attribute (forum_name) |
| 190 'forum_name': 'LOLCat Forum', |
| 191 # This is your range key attribute (subject) |
| 192 'subject': 'Check this out!' |
| 193 'Body': 'http://url_to_lolcat.gif', |
| 194 'ReceivedTime': '12/9/2011 11:36:03 PM', |
| 195 'SentBy': 'User A', |
| 196 } |
| 197 |
| 198 Updating Items |
| 199 -------------- |
| 200 |
| 201 To update an item's attributes, simply retrieve it, modify the value, then |
| 202 :py:meth:`Item.put <boto.dynamodb.item.Item.put>` it again:: |
| 203 |
| 204 >>> table = conn.get_table('messages') |
| 205 >>> item = table.get_item( |
| 206 hash_key='LOLCat Forum', |
| 207 range_key='Check this out!' |
| 208 ) |
| 209 >>> item['SentBy'] = 'User B' |
| 210 >>> item.put() |
| 211 |
| 212 Deleting Items |
| 213 -------------- |
| 214 |
| 215 To delete items, use the |
| 216 :py:meth:`Item.delete <boto.dynamodb.item.Item.delete>` method:: |
| 217 |
| 218 >>> table = conn.get_table('messages') |
| 219 >>> item = table.get_item( |
| 220 hash_key='LOLCat Forum', |
| 221 range_key='Check this out!' |
| 222 ) |
| 223 >>> item.delete() |
| 224 |
| 225 Deleting Tables |
| 226 --------------- |
| 227 |
| 228 .. WARNING:: |
| 229 Deleting a table will also **permanently** delete all of its contents without
prompt. Use carefully. |
| 230 |
| 231 There are two easy ways to delete a table. Through your top-level |
| 232 :py:class:`Layer2 <boto.dynamodb.layer2.Layer2>` object:: |
| 233 |
| 234 >>> conn.delete_table(table) |
| 235 |
| 236 Or by getting the table, then using |
| 237 :py:meth:`Table.delete <boto.dynamodb.table.Table.delete>`:: |
| 238 |
| 239 >>> table = conn.get_table('messages') |
| 240 >>> table.delete() |
| OLD | NEW |