Skip to Content
Course content

288: Connecting to MongoDB with PyMongo

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've seen this happen dozens of times with junior devs moving from SQL to NoSQL: they write a few lines of PyMongo code to define a database and a collection, run the script, and then panic when they open their MongoDB GUI (like Compass) and see... absolutely nothing. They assume the connection failed or the code didn't execute because the database they "created" isn't appearing in the list.

The "Instant Database" Illusion

The misconception is that calling client.my_database_name actually tells MongoDB to create that database on the disk immediately. In a relational world, you're used to CREATE DATABASE being a concrete command that does something right now. MongoDB doesn't work like that.

from pymongo import MongoClient

# This doesn't actually "do" anything on the server yet
client = MongoClient("mongodb://localhost:27017/")
db = client["game_stats"] 
collection = db["player_scores"]

print("Database created!") # This is a lie.

If you run the code above, PyMongo creates a local Python object that represents that database, but it doesn't send a single byte of "creation" data to the server. MongoDB is lazy. It won't actually create the database or the collection until you insert the first piece of actual data. It's a "create-on-write" system.

Lazy Initialization and Connection Pooling

To actually make the database exist, you have to put something in it. But before we do that, let's talk about the MongoClient itself. Another mistake I see is people treating the client like a file handle—opening it, doing one query, and closing it immediately. Don't do that. The MongoClient maintains a connection pool. It's designed to be instantiated once and shared across your application. Creating a new client for every request is a great way to kill your app's performance via connection overhead.

Here is how you actually establish a connection and force the database into existence by inserting a record. Let's imagine we're building a tracker for a gaming leaderboard.

from pymongo import MongoClient

# 1. Establish the client (do this once for your app)
client = MongoClient("mongodb://localhost:27017/")

# 2. Access the database and collection (still lazy)
db = client["gaming_hub"]
scores = db["high_scores"]

# 3. The "Magic Moment": Inserting data
# This is the exact line that triggers MongoDB to actually create the DB and Collection
player_data = {
    "username": "CyberKnight_99",
    "score": 15400,
    "level": 42,
    "achievements": ["First Blood", "Dragon Slayer"]
}

result = scores.insert_one(player_data)

print(f"Inserted document ID: {result.inserted_id}")

Handling Connection Strings and Security

In the example above, I used localhost, but in the real world, you'll likely use MongoDB Atlas. Your connection string will look like a long URI (mongodb+srv://...). I strongly suggest you never hardcode these strings directly in your script. If you push a script with a plaintext password to GitHub, bots will find it and wipe your database for ransom within minutes. I've seen it happen. Use environment variables or a .env file to keep your credentials safe.

Once you have your MongoClient set up and your first document inserted, you've crossed the hardest hurdle. The rest is just learning the query language, which feels much more like manipulating Python dictionaries than writing traditional SQL.




📋 Practical Task

Building a Tabletop RPG Character Vault

Your goal is to create a Python script that connects to a MongoDB instance and initializes a "Character Vault" for a tabletop RPG. Instead of just one record, you need to ensure the database is properly populated so it becomes visible in your management tool.

Requirements:

  • Establish a connection to a local MongoDB instance (mongodb://localhost:27017/).
  • Target a database named rpg_vault and a collection named characters.
  • Create a list of at least three different character dictionaries. Each character should have:
    • A name (string)
    • A class (e.g., "Paladin", "Rogue", "Wizard")
    • A stats dictionary containing strength, dexterity, and intelligence.
    • An inventory list of items.
  • Use insert_many() to upload all characters in a single call.
  • Print the total number of characters successfully inserted to the console.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.