|
| 1 | +Database |
| 2 | +======== |
| 3 | + |
| 4 | +You can build paths to your data by using the ``child()`` method. |
| 5 | + |
| 6 | +.. code-block:: python |
| 7 | +
|
| 8 | + db = firebaseApp.database() |
| 9 | + db.child("users").child("Morty") |
| 10 | +.. |
| 11 | +
|
| 12 | + .. note:: |
| 13 | + Each of the following methods accepts a user token: |
| 14 | + ``get()``, ``push()``, ``set()``, ``update()``, |
| 15 | + ``remove()`` and ``stream()``. |
| 16 | + |
| 17 | + |
| 18 | +Save Data |
| 19 | +--------- |
| 20 | + |
| 21 | + |
| 22 | +push |
| 23 | +^^^^ |
| 24 | + |
| 25 | +To save data with a unique, auto-generated, timestamp-based key, use the |
| 26 | +``push()`` method. |
| 27 | + |
| 28 | +.. code-block:: python |
| 29 | +
|
| 30 | + data = {"name": "Mortimer 'Morty' Smith"} |
| 31 | + db.child("users").push(data) |
| 32 | +.. |
| 33 | +
|
| 34 | +set |
| 35 | +^^^ |
| 36 | + |
| 37 | +To create your own keys use the ``set()`` method. The key in the example |
| 38 | +below is "Morty". |
| 39 | + |
| 40 | +.. code-block:: python |
| 41 | +
|
| 42 | + data = {"name": "Mortimer 'Morty' Smith"} |
| 43 | + db.child("users").child("Morty").set(data) |
| 44 | +.. |
| 45 | +
|
| 46 | +update |
| 47 | +^^^^^^ |
| 48 | + |
| 49 | +To update data for an existing entry use the ``update()`` method. |
| 50 | + |
| 51 | +.. code-block:: python |
| 52 | +
|
| 53 | + db.child("users").child("Morty").update({"name": "Mortiest Morty"}) |
| 54 | +.. |
| 55 | +
|
| 56 | +remove |
| 57 | +^^^^^^ |
| 58 | + |
| 59 | +To delete data for an existing entry use the ``remove()`` method. |
| 60 | + |
| 61 | +.. code-block:: python |
| 62 | +
|
| 63 | + db.child("users").child("Morty").remove() |
| 64 | +.. |
| 65 | +
|
| 66 | +multi-location updates |
| 67 | +^^^^^^^^^^^^^^^^^^^^^^ |
| 68 | + |
| 69 | +You can also perform `multi-location |
| 70 | +updates <https://www.firebase.com/blog/2015-09-24-atomic-writes-and-more.html>`__ |
| 71 | +with the ``update()`` method. |
| 72 | + |
| 73 | +.. code-block:: python |
| 74 | +
|
| 75 | + data = { |
| 76 | + "users/Morty/": { |
| 77 | + "name": "Mortimer 'Morty' Smith" |
| 78 | + }, |
| 79 | + "users/Rick/": { |
| 80 | + "name": "Rick Sanchez" |
| 81 | + } |
| 82 | + } |
| 83 | +
|
| 84 | + db.update(data) |
| 85 | +.. |
| 86 | +
|
| 87 | +To perform multi-location writes to new locations we can use the |
| 88 | +``generate_key()`` method. |
| 89 | + |
| 90 | +.. code-block:: python |
| 91 | +
|
| 92 | + data = { |
| 93 | + "users/"+ref.generate_key(): { |
| 94 | + "name": "Mortimer 'Morty' Smith" |
| 95 | + }, |
| 96 | + "users/"+ref.generate_key(): { |
| 97 | + "name": "Rick Sanchez" |
| 98 | + } |
| 99 | + } |
| 100 | +
|
| 101 | + db.update(data) |
| 102 | +.. |
| 103 | +
|
| 104 | + |
| 105 | +Retrieve Data |
| 106 | +------------- |
| 107 | + |
| 108 | + |
| 109 | +val |
| 110 | +^^^ |
| 111 | + |
| 112 | +Queries return a PyreResponse object. Calling ``val()`` on these objects |
| 113 | +returns the query data. |
| 114 | + |
| 115 | +.. code-block:: python |
| 116 | +
|
| 117 | + users = db.child("users").get() |
| 118 | + print(users.val()) # {"Morty": {"name": "Mortimer 'Morty' Smith"}, "Rick": {"name": "Rick Sanchez"}} |
| 119 | +.. |
| 120 | +
|
| 121 | +key |
| 122 | +^^^ |
| 123 | + |
| 124 | +Calling ``key()`` returns the key for the query data. |
| 125 | + |
| 126 | +.. code-block:: python |
| 127 | +
|
| 128 | + user = db.child("users").get() |
| 129 | + print(user.key()) # users |
| 130 | +.. |
| 131 | +
|
| 132 | +each |
| 133 | +^^^^ |
| 134 | + |
| 135 | +Returns a list of objects on each of which you can call ``val()`` and |
| 136 | +``key()``. |
| 137 | + |
| 138 | +.. code-block:: python |
| 139 | +
|
| 140 | + all_users = db.child("users").get() |
| 141 | + for user in all_users.each(): |
| 142 | + print(user.key()) # Morty |
| 143 | + print(user.val()) # {name": "Mortimer 'Morty' Smith"} |
| 144 | +.. |
| 145 | +
|
| 146 | +get |
| 147 | +^^^ |
| 148 | + |
| 149 | +To return data from a path simply call the ``get()`` method. |
| 150 | + |
| 151 | +.. code-block:: python |
| 152 | +
|
| 153 | + all_users = db.child("users").get() |
| 154 | +.. |
| 155 | +
|
| 156 | +Conditional Requests |
| 157 | +^^^^^^^^^^^^^^^^^^^^ |
| 158 | + |
| 159 | +It's possible to do conditional sets and removes by using the |
| 160 | +``conditional_set()`` and ``conitional_remove()`` methods respectively. |
| 161 | +You can read more about conditional requests in Firebase |
| 162 | +`here <https://firebase.google.com/docs/reference/rest/database/#section-conditional-requests>`__. |
| 163 | + |
| 164 | +To use these methods, you first get the ETag of a particular path by |
| 165 | +using the ``get_etag()`` method. You can then use that tag in your |
| 166 | +conditional request. |
| 167 | + |
| 168 | +.. code-block:: python |
| 169 | +
|
| 170 | + etag = db.child("users").child("Morty").get_etag() |
| 171 | + data = {"name": "Mortimer 'Morty' Smith"} |
| 172 | + db.child("users").child("Morty").conditional_set(data, etag) |
| 173 | +.. |
| 174 | +
|
| 175 | +If the passed ETag does not match the ETag of the path in the database, |
| 176 | +the data will not be written, and both conditional request methods will |
| 177 | +return a single key-value pair with the new ETag to use of the following |
| 178 | +form: |
| 179 | + |
| 180 | +.. code-block:: json |
| 181 | +
|
| 182 | + { "ETag": "8KnE63B6HiKp67Wf3HQrXanujSM=" } |
| 183 | +.. |
| 184 | +
|
| 185 | +Here's an example of checking whether or not a conditional removal was |
| 186 | +successful: |
| 187 | + |
| 188 | +.. code-block:: python |
| 189 | +
|
| 190 | + etag = db.child("users").child("Morty").get_etag() |
| 191 | + response = db.child("users").child("Morty").conditional_remove(etag) |
| 192 | +
|
| 193 | + if "ETag" in response: |
| 194 | + etag = response["ETag"] # our ETag was out-of-date |
| 195 | + else: |
| 196 | + print("We removed the data successfully!") |
| 197 | +.. |
| 198 | +
|
| 199 | +shallow |
| 200 | +^^^^^^^ |
| 201 | + |
| 202 | +To return just the keys at a particular path use the ``shallow()`` |
| 203 | +method. |
| 204 | + |
| 205 | +.. code-block:: python |
| 206 | +
|
| 207 | + all_user_ids = db.child("users").shallow().get() |
| 208 | +.. |
| 209 | +
|
| 210 | + .. note:: |
| 211 | + ``shallow()`` can not be used in conjunction with any complex |
| 212 | + queries. |
| 213 | + |
| 214 | +streaming |
| 215 | +^^^^^^^^^ |
| 216 | + |
| 217 | +You can listen to live changes to your data with the ``stream()`` |
| 218 | +method. |
| 219 | + |
| 220 | +.. code-block:: python |
| 221 | +
|
| 222 | + def stream_handler(message): |
| 223 | + print(message["event"]) # put |
| 224 | + print(message["path"]) # /-K7yGTTEp7O549EzTYtI |
| 225 | + print(message["data"]) # {'title': 'Firebase', "body": "etc..."} |
| 226 | +
|
| 227 | + my_stream = db.child("posts").stream(stream_handler) |
| 228 | +.. |
| 229 | +
|
| 230 | +You should at least handle ``put`` and ``patch`` events. Refer to |
| 231 | +`"Streaming from the REST |
| 232 | +API" <https://firebase.google.com/docs/reference/rest/database/#section-streaming>`__ |
| 233 | +for details. |
| 234 | + |
| 235 | +You can also add a ``stream_id`` to help you identify a stream if you |
| 236 | +have multiple running: |
| 237 | + |
| 238 | +.. code-block:: python |
| 239 | +
|
| 240 | + my_stream = db.child("posts").stream(stream_handler, stream_id="new_posts") |
| 241 | +.. |
| 242 | +
|
| 243 | +close the stream |
| 244 | +^^^^^^^^^^^^^^^^ |
| 245 | + |
| 246 | +.. code-block:: python |
| 247 | +
|
| 248 | + my_stream.close() |
| 249 | +.. |
| 250 | +
|
| 251 | + |
| 252 | +Complex Queries |
| 253 | +--------------- |
| 254 | + |
| 255 | +Queries can be built by chaining multiple query parameters together. |
| 256 | + |
| 257 | +.. code-block:: python |
| 258 | +
|
| 259 | + users_by_name = db.child("users").order_by_child("name").limit_to_first(3).get() |
| 260 | +.. |
| 261 | +
|
| 262 | +This query will return the first three users ordered by name. |
| 263 | + |
| 264 | +order_by_child |
| 265 | +^^^^^^^^^^^^^^ |
| 266 | + |
| 267 | +We begin any complex query with ``order_by_child()``. |
| 268 | + |
| 269 | +.. code-block:: python |
| 270 | +
|
| 271 | + users_by_name = db.child("users").order_by_child("name").get() |
| 272 | +.. |
| 273 | +
|
| 274 | +This query will return users ordered by name. |
| 275 | + |
| 276 | +equal_to |
| 277 | +^^^^^^^^ |
| 278 | + |
| 279 | +Return data with a specific value. |
| 280 | + |
| 281 | +.. code-block:: python |
| 282 | +
|
| 283 | + users_by_score = db.child("users").order_by_child("score").equal_to(10).get() |
| 284 | +.. |
| 285 | +
|
| 286 | +This query will return users with a score of 10. |
| 287 | + |
| 288 | +start_at and end_at |
| 289 | +^^^^^^^^^^^^^^^^^^^ |
| 290 | + |
| 291 | +Specify a range in your data. |
| 292 | + |
| 293 | +.. code-block:: python |
| 294 | +
|
| 295 | + users_by_score = db.child("users").order_by_child("score").start_at(3).end_at(10).get() |
| 296 | +.. |
| 297 | +
|
| 298 | +This query returns users ordered by score and with a score between 3 and |
| 299 | +10. |
| 300 | + |
| 301 | +limit_to_first and limit_to_last |
| 302 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 303 | + |
| 304 | +Limits data returned. |
| 305 | + |
| 306 | +.. code-block:: python |
| 307 | +
|
| 308 | + users_by_score = db.child("users").order_by_child("score").limit_to_first(5).get() |
| 309 | +.. |
| 310 | +
|
| 311 | +This query returns the first five users ordered by score. |
| 312 | + |
| 313 | +order_by_key |
| 314 | +^^^^^^^^^^^^ |
| 315 | + |
| 316 | +When using ``order_by_key()`` to sort your data, data is returned in |
| 317 | +ascending order by key. |
| 318 | + |
| 319 | +.. code-block:: python |
| 320 | +
|
| 321 | + users_by_key = db.child("users").order_by_key().get() |
| 322 | +.. |
| 323 | +
|
| 324 | +order_by_value |
| 325 | +^^^^^^^^^^^^^^ |
| 326 | + |
| 327 | +When using ``order_by_value()``, children are ordered by their value. |
| 328 | + |
| 329 | +.. code-block:: python |
| 330 | +
|
| 331 | + users_by_value = db.child("users").order_by_value().get() |
| 332 | +.. |
0 commit comments