1

I am using a local ("community") version of MongoDB, Python 3, and pymongo.

First, I had been manually starting the MongoDB daemon (mongod) in a separate shell and then running my Python script. This script uses pymongo to successfully instantiate the MongoDB client (mongo) and interact with my database. When my script terminated, I would manually terminate the daemon by sending the kill command to its PID.

While this is all fine and dandy, the goal of this script is to automate as much as possible. As such, I want to incorporate the starting and terminating of the daemon via script, but it must be asynchronous so as to not keep the main code from running. I tried using subprocess.Popen(), and then a Thread class with the daemon attribute set to true -- yet I still see the mongod process up and running when I call ps after my entire program exits.

Below is the Thread class:

class MongoDaemonThread(object):
    def __init__(self):
        thread = threading.Thread(target=self.run, args=())
        thread.daemon = True
        thread.start()

    def run(self):
        mongo_daemon = subprocess.Popen('/Users/<me>/.mongodb/bin/mongod')
        return mongo_daemon

And here is the function in which I interact with the database:

def db_write(report_list, args):
    # ...
    client = MongoClient()
    db = client.cbf
    # ...
    reports = db.reports
    for report in report_list:
        report_id = reports.insert_one(report).inserted_id
    # ...

What I'm looking to do is the following, all through Python (be it one script or multiple):

  1. enter code
  2. start mongod (asynchronously to rest of code/in background and let it listen for connections from a Mongo client) (#TODO)
  3. create a Mongo client
  4. interface with my database through said client
  5. terminate the Mongo daemon (#TODO)
  6. exit code/terminate program

Is threading the right way to do this? If so, what am I doing wrong? If threading is not the answer, what method might you suggest I use instead?

jiccan
  • 89
  • 12

2 Answers2

2

First of all, you shouldn't start the mongod process from python. mongod should be started and stopped from shell. Because database must always be ready for connections. But IF you really want to do it from python, you can still use:

from subprocess import call
call(["mongod","&"])

to start the mongod process.

To end the process:

from subprocess import call
call(["pkill", "mongod","&"])
ramazan polat
  • 7,111
  • 1
  • 48
  • 76
  • In the future, we will be migrating the start of the daemon elsewhere, but for this "simulated" task, since the database was created for this one and only purpose, and is only interacted with through this one program, I'd like to get everything bundled together in Python. (I guess I could write a bash script wrapping around it all, but I already have one Python script that calls the script I have been talking about multiple times, and I feel as though I am making things unnecessarily complicated.) _That being said..._ using `call(["mongod"])` and `call(["pkill", "mongod"])` returned an error. – jiccan Jul 13 '18 at 19:41
  • Also, according to [this SO post](https://stackoverflow.com/questions/46492913/how-to-format-a-subprocess-call-statement) ... `subprocess.call()` will "run the command described by args, wait for command to complete, then return the returncode attribute." I do _not_ want to wait for the command to complete. – jiccan Jul 13 '18 at 20:01
  • @jiccan I forgot to put an ``&`` after each command. Corrected. – ramazan polat Jul 13 '18 at 21:36
0

This answer -- using p = Popen() and then p.terminate() -- seemed to be exactly what I was looking for.

jiccan
  • 89
  • 12