How to deal with DBref in schema and dataclass in python

Hello MongoDB-community,

I hope you can help me with a simple question. There is the possibility to insert DBref in a document so the document that contains the DBref is referencing another document in the same and/or different collection. This is awsome but I have a few little questions you may help me with.

  1. DBref manual link
    This is the link to the DBref manual it is written that you should name you fields with $ref and $_id. Is this necessary or would ref and _id also work?

If the $ is necessary, how should i deal with it in a python dataclass because there Iā€™m not allowed to name a dataclass field with a beginning $-sign.

Thanks a lot for you help beforehand!

Hi @Marco_Fischer and welcome to the community!!

The following sample code below would give an explanation on how to use the DBRefs in MongoDB using Python

import pymongo
from pymongo import MongoClient
from bson.dbref import DBRef

client = pymongo.MongoClient("mongodb://localhost:27017")
db = client['test']
db.authors.drop()
db.books.drop()

authors = [
    {'_id': 0, 'name': 'Conan Doyle'},
    {'_id': 1, 'name': 'Homer'}
]
db.authors.insert_many(authors)

books = [
    {'_id': 0 ,'title': 'Ilyad', 'author': DBRef('author', 1)},
    {'_id': 1 ,'title': 'Adventures', 'author': DBRef('author', 0)},
    {'_id': 2 ,'title': 'Odyssey', 'author': DBRef('author', 1)}
]
db.books.insert_many(books)

books_by_conan = list(db.books.find({'author.$id': 0}))
books_by_homer = list(db.books.find({'author.$id': 1}))

print(f'Books by Conan: {books_by_conan}')
print(f'Books by Homer: {books_by_homer}')

The result of which would look like:

Books by Conan: [{ā€˜_idā€™: 1, ā€˜titleā€™: ā€˜Adventuresā€™, ā€˜authorā€™: DBRef(ā€˜authorā€™, 0)}]

Books by Homer: [{ā€˜_idā€™: 0, ā€˜titleā€™: ā€˜Ilyadā€™, ā€˜authorā€™: DBRef(ā€˜authorā€™, 1)}, {ā€˜_idā€™: 2, ā€˜titleā€™: ā€˜Odysseyā€™, ā€˜authorā€™: DBRef(ā€˜authorā€™, 1)}]

In the example above, author.$id is referencing the authorā€™s _id values.
Here using DBRef provides a slight advantage of making it explicit that the field is referencing another collection.

However, one main disadvantage is that DBRef does not work with $lookup.

Please note that as mentioned in the page Database References, unless you have a specific & compelling reason to use DBRef, itā€™s strongly recommended to use manual references instead (for example, putting the value of the authorā€™s _id directly in the author field, in the example above)

I would also suggest against using DBRef or manual references to replicate a tabular database design and using it like a foreign key.

Please see the recommended MongoDB Schema Design Best Practices | MongoDB to learn more.

Thanks
Aasawari

3 Likes

Thank you a lot Aasawari! Now it works and the hint i needed was the ā€œfrom bson.dbref import DBRefā€. Now Iā€™m creating an object out of a dataclass and transpose it to a dict. Afterwards Iā€™m able to create an array for a field with DBRefs and it also passes the validation.

You made my day!! :wink: :raised_hands:

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.