Skip to content

Commit 3cfd8ee

Browse files
committed
fixes
1 parent 4cbeeed commit 3cfd8ee

File tree

3 files changed

+223
-80
lines changed

3 files changed

+223
-80
lines changed

source/data-formats/custom-types.txt

Lines changed: 210 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,54 @@ the driver doesn't understand. For example, the
2929
BSON library's ``Decimal128`` type is distinct
3030
from Python's built-in ``Decimal`` type. Attempting
3131
to save an instance of ``Decimal`` with {+driver-short+} results in an
32-
``InvalidDocument`` exception, as shown in the following code example:
32+
``InvalidDocument`` exception, as shown in the following code example. Select the
33+
:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code.
3334

34-
.. io-code-block::
35-
:copyable: true
35+
.. tabs::
36+
37+
.. tab:: Synchronous
38+
:tabid: sync
39+
40+
.. io-code-block::
41+
:copyable: true
42+
43+
.. input::
44+
:language: python
45+
46+
from decimal import Decimal
47+
48+
num = Decimal("45.321")
49+
db["coll"].insert_one({"num": num})
50+
51+
.. output::
52+
:language: shell
53+
54+
Traceback (most recent call last):
55+
...
56+
bson.errors.InvalidDocument: cannot encode object: Decimal('45.321'), of
57+
type: <class 'decimal.Decimal'>
58+
59+
.. tab:: Asynchronous
60+
:tabid: async
61+
62+
.. io-code-block::
63+
:copyable: true
3664

37-
.. input::
38-
:language: python
65+
.. input::
66+
:language: python
3967

40-
from decimal import Decimal
68+
from decimal import Decimal
4169

42-
num = Decimal("45.321")
43-
db["coll"].insert_one({"num": num})
70+
num = Decimal("45.321")
71+
await db["coll"].insert_one({"num": num})
4472

45-
.. output::
46-
:language: shell
73+
.. output::
74+
:language: shell
4775

48-
Traceback (most recent call last):
49-
...
50-
bson.errors.InvalidDocument: cannot encode object: Decimal('45.321'), of
51-
type: <class 'decimal.Decimal'>
76+
Traceback (most recent call last):
77+
...
78+
bson.errors.InvalidDocument: cannot encode object: Decimal('45.321'), of
79+
type: <class 'decimal.Decimal'>
5280

5381
The following sections show how to define a custom type for this ``Decimal`` type.
5482

@@ -154,46 +182,97 @@ object as a keyword argument. Pass your ``CodecOptions`` object to the
154182
codec_options = CodecOptions(type_registry=type_registry)
155183
collection = db.get_collection("test", codec_options=codec_options)
156184

157-
You can then encode and decode instances of the ``Decimal`` class:
185+
You can then encode and decode instances of the ``Decimal`` class. Select the
186+
:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code.
158187

159-
.. io-code-block::
160-
:copyable: true
188+
.. tabs::
189+
190+
.. tab:: Synchronous
191+
:tabid: sync
161192

162-
.. input::
163-
:language: python
193+
.. io-code-block::
194+
:copyable: true
164195

165-
import pprint
166-
167-
collection.insert_one({"num": Decimal("45.321")})
168-
my_doc = collection.find_one()
169-
pprint.pprint(my_doc)
196+
.. input::
197+
:language: python
170198

171-
.. output::
172-
:language: shell
173-
174-
{'_id': ObjectId('...'), 'num': Decimal('45.321')}
199+
import pprint
200+
201+
collection.insert_one({"num": Decimal("45.321")})
202+
my_doc = collection.find_one()
203+
pprint.pprint(my_doc)
204+
205+
.. output::
206+
:language: shell
207+
208+
{'_id': ObjectId('...'), 'num': Decimal('45.321')}
209+
210+
.. tab:: Asynchronous
211+
:tabid: async
212+
213+
.. io-code-block::
214+
:copyable: true
215+
216+
.. input::
217+
:language: python
218+
219+
import pprint
220+
221+
await collection.insert_one({"num": Decimal("45.321")})
222+
my_doc = await collection.find_one()
223+
pprint.pprint(my_doc)
224+
225+
.. output::
226+
:language: shell
227+
228+
{'_id': ObjectId('...'), 'num': Decimal('45.321')}
175229

176230
To see how MongoDB stores an instance of the custom type,
177231
create a new collection object without the customized codec options, then use it
178232
to retrieve the document containing the custom type. The following example shows
179233
that {+driver-short+} stores an instance of the ``Decimal`` class as a ``Decimal128``
180-
value:
234+
value. Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the
235+
corresponding code.
236+
237+
.. tabs::
238+
239+
.. tab:: Synchronous
240+
:tabid: sync
181241

182-
.. io-code-block::
183-
:copyable: true
242+
.. io-code-block::
243+
:copyable: true
184244

185-
.. input::
186-
:language: python
245+
.. input::
246+
:language: python
187247

188-
import pprint
248+
import pprint
189249

190-
new_collection = db.get_collection("test")
191-
pprint.pprint(new_collection.find_one())
250+
new_collection = db.get_collection("test")
251+
pprint.pprint(new_collection.find_one())
192252

193-
.. output::
194-
:language: shell
253+
.. output::
254+
:language: shell
195255

196-
{'_id': ObjectId('...'), 'num': Decimal128('45.321')}
256+
{'_id': ObjectId('...'), 'num': Decimal128('45.321')}
257+
258+
.. tab:: Asynchronous
259+
:tabid: async
260+
261+
.. io-code-block::
262+
:copyable: true
263+
264+
.. input::
265+
:language: python
266+
267+
import pprint
268+
269+
new_collection = db.get_collection("test")
270+
pprint.pprint(await new_collection.find_one())
271+
272+
.. output::
273+
:language: shell
274+
275+
{'_id': ObjectId('...'), 'num': Decimal128('45.321')}
197276

198277
Encode a Subtype
199278
----------------
@@ -209,23 +288,48 @@ return its value as an integer:
209288
return int(self)
210289

211290
If you try to save an instance of the ``DecimalInt`` class without first registering a type
212-
codec for it, {+driver-short+} raises an error:
291+
codec for it, {+driver-short+} raises an error. Select the
292+
:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code.
293+
294+
.. tabs::
295+
296+
.. tab:: Synchronous
297+
:tabid: sync
213298

214-
.. io-code-block::
215-
:copyable: true
299+
.. io-code-block::
300+
:copyable: true
301+
302+
.. input::
303+
:language: python
304+
305+
collection.insert_one({"num": DecimalInt("45.321")})
306+
307+
.. output::
308+
:language: shell
309+
310+
Traceback (most recent call last):
311+
...
312+
bson.errors.InvalidDocument: cannot encode object: Decimal('45.321'),
313+
of type: <class 'decimal.Decimal'>
216314

217-
.. input::
218-
:language: python
315+
.. tab:: Asynchronous
316+
:tabid: async
317+
318+
.. io-code-block::
319+
:copyable: true
219320

220-
collection.insert_one({"num": DecimalInt("45.321")})
321+
.. input::
322+
:language: python
323+
324+
await collection.insert_one({"num": DecimalInt("45.321")})
221325

222-
.. output::
223-
:language: shell
326+
.. output::
327+
:language: shell
224328

225-
Traceback (most recent call last):
226-
...
227-
bson.errors.InvalidDocument: cannot encode object: Decimal('45.321'),
228-
of type: <class 'decimal.Decimal'>
329+
Traceback (most recent call last):
330+
...
331+
bson.errors.InvalidDocument: cannot encode object: Decimal('45.321'),
332+
of type: <class 'decimal.Decimal'>
229333

230334
To encode an instance of the ``DecimalInt`` class, you must define a type codec for
231335
the class. This type codec must inherit from the parent class's codec, ``DecimalCodec``,
@@ -240,31 +344,64 @@ as shown in the following example:
240344
return DecimalInt
241345

242346
You can then add the sublcass's type codec to the type registry and encode instances
243-
of the custom type:
347+
of the custom type. Select the
348+
:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code.
244349

245-
.. io-code-block::
246-
:copyable: true
350+
.. tabs::
247351

248-
.. input::
249-
:language: python
352+
.. tab:: Synchronous
353+
:tabid: sync
354+
355+
.. io-code-block::
356+
:copyable: true
250357

251-
import pprint
252-
from bson.codec_options import CodecOptions
358+
.. input::
359+
:language: python
253360

254-
decimal_int_codec = DecimalIntCodec()
255-
type_registry = TypeRegistry([decimal_codec, decimal_int_codec])
256-
codec_options = CodecOptions(type_registry=type_registry)
361+
import pprint
362+
from bson.codec_options import CodecOptions
257363

258-
collection = db.get_collection("test", codec_options=codec_options)
259-
collection.insert_one({"num": DecimalInt("45.321")})
260-
261-
my_doc = collection.find_one()
262-
pprint.pprint(my_doc)
364+
decimal_int_codec = DecimalIntCodec()
365+
type_registry = TypeRegistry([decimal_codec, decimal_int_codec])
366+
codec_options = CodecOptions(type_registry=type_registry)
263367

264-
.. output::
265-
:language: shell
368+
collection = db.get_collection("test", codec_options=codec_options)
369+
collection.insert_one({"num": DecimalInt("45.321")})
370+
371+
my_doc = collection.find_one()
372+
pprint.pprint(my_doc)
373+
374+
.. output::
375+
:language: shell
376+
377+
{'_id': ObjectId('...'), 'num': Decimal('45.321')}
266378

267-
{'_id': ObjectId('...'), 'num': Decimal('45.321')}
379+
.. tab:: Asynchronous
380+
:tabid: async
381+
382+
.. io-code-block::
383+
:copyable: true
384+
385+
.. input::
386+
:language: python
387+
388+
import pprint
389+
from bson.codec_options import CodecOptions
390+
391+
decimal_int_codec = DecimalIntCodec()
392+
type_registry = TypeRegistry([decimal_codec, decimal_int_codec])
393+
codec_options = CodecOptions(type_registry=type_registry)
394+
395+
collection = db.get_collection("test", codec_options=codec_options)
396+
await collection.insert_one({"num": DecimalInt("45.321")})
397+
398+
my_doc = collection.find_one()
399+
pprint.pprint(my_doc)
400+
401+
.. output::
402+
:language: shell
403+
404+
{'_id': ObjectId('...'), 'num': Decimal('45.321')}
268405

269406
.. note::
270407

@@ -306,8 +443,8 @@ The following code example shows this process:
306443
collection = db.get_collection("test", codec_options=codec_options)
307444

308445
You can then use this reference to a collection to store instances of the ``Decimal``
309-
class. Select the :guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the
310-
corresponding code.
446+
class. Select the
447+
:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code.
311448

312449
.. tabs::
313450

@@ -409,8 +546,8 @@ back into Python objects:
409546
return value
410547

411548
You can then add the ``PickledBinaryDecoder`` to the codec options for a collection
412-
and use it to encode and decode your custom types. Select the :guilabel:`Synchronous` or
413-
:guilabel:`Asynchronous` tab to see the corresponding code.
549+
and use it to encode and decode your custom types. Select the
550+
:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code.
414551

415552
.. tabs::
416553

0 commit comments

Comments
 (0)