Jere
Jere

Reputation: 1266

Can I restore a mongo db from within mongo shell?

Dumping and restoring a mongo db seems fairly straightforward when you are using the shell anyway: you just use the commands mongorestore and mongodump. But if I am not mistaken, these commands require you to leave your active mongo shell.

Furthermore, when writing in Python or Prolog I have different ways of communicating with mongo. I can either use PyMonogo or in my case, I am communicating via RosProlog. Both can execute mongo shell commands but I can't figure out a way to execute something similar to mongorestore and mongodump.

Of course I could use os.system() in Python (or process_create/3 in prolog) to execute shell-commands, but it seems very ugly and I would like to avoid it. I could also write a .bson-parser myself but is that really necessary? Is there really no equivalent in the mongo shell?

Upvotes: 0

Views: 1083

Answers (2)

Belly Buster
Belly Buster

Reputation: 8844

This python solution works on windows and linux; sure it's a bit hacky but hardly ugly.

import subprocess
output = subprocess.run(['mongodump', '--uri', 'mongodb://localhost', '--readPreference', 'primary'], capture_output=True)
print(output)

Add in whatever additional parameters you need, e.g. f'--archive={my_file}'

Upvotes: 1

Alex Blex
Alex Blex

Reputation: 37098

mongodump and mongorestore are OS level utilities written in golang https://github.com/mongodb/mongo-tools. You indeed need to run them outside the mongo shell.

The recommended way is to use standard mongodump and mongorestore as subprocesses yet there is no magic there and you can do the same in Python.

From https://jira.mongodb.org/browse/PYTHON-664:

from bson import BSON, decode_all
from pymongo import MongoClient
 
client = MongoClient()
source_collection = client.db.collection
 
# Dump.
with open('file.bson', 'wb+') as f:
    for doc in source_collection.find():
        f.write(BSON.encode(doc))
 
# Restore.
target_collection = client.db.collection2
with open('file.bson', 'rb') as f:
    target_collection.insert(decode_all(f.read()))

It won't be as efficient, the backups won't be compatible with standard backups, and you may miss some edge cases without dumping oplog.

Upvotes: 2

Related Questions