# Getting Started with PyMongo

[PyMongo](https://pymongo.readthedocs.io/) is the official MongoDB driver for Python. It gives you a simple way to work with MongoDB databases in your Python applications.

PyMongo has everything you need to work with MongoDB: connection pooling, automatic reconnection, CRUD operations, and support for advanced MongoDB features like aggregation and geospatial queries. 

This guide will show you how to set up PyMongo and use it in your applications. You'll learn how to connect to MongoDB and perform common database operations. 

[ad-logs]

## Prerequisites
Before starting, make sure you have Python 3.7 or newer, MongoDB installed or access to a MongoDB instance, and a basic understanding of Python and databases.

To check if MongoDB is running, use the following on macOS:

```command
brew services info mongodb-community
```
```text
[output]
mongodb-community (homebrew.mxcl.mongodb-community)
Running: ✔
Loaded: ✔
...
```

On Ubuntu, run `sudo systemctl status mongod` and check for `active (running)`. 

## Setting up PyMongo
Before writing code, organize your project by creating a folder and setting up a virtual environment to keep dependencies isolated.



First, create the project directory and move into it:

```command
mkdir pymongo-demo && cd pymongo-demo
```

Then, create a virtual environment:

```command
python3 -m venv venv
```

Activate the environment:

```command
source venv/bin/activate
```

Follwoing that, install PyMongo using `pip`:

```command
pip install pymongo
```
Before we write any code, let's understand how PyMongo connects your Python application to MongoDB. The diagram below illustrates the complete architecture of a PyMongo application:


![Diagram showing PyMongo architecture: Python Application using PyMongo connects to MongoDB Server through MongoClient. The server contains Databases, which hold Collections, which store Documents. Shows the complete data flow from code to stored data](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/565be28a-19b6-40d9-ae90-3eeba830cb00/lg1x =2484x888)

Your Python app uses the PyMongo library to connect to MongoDB through `MongoClient`. The MongoDB server manages databases. Each database contains collections, and collections store documents. Documents are structured like JSON and allow for flexible, schema-free data. This hierarchy helps keep everything organized and easy to work with.

Now let's create the connection logic so your app can talk to the database.

Now, create a Python file named `mongo_client.py` with this code:

```python
[label mongo_client.py]
from pymongo import MongoClient

def get_database():
    # Connect to MongoDB
    client = MongoClient('mongodb://localhost:27017/')
    
    # Get the database (creates it if it doesn't exist)
    return client['pymongo_tutorial']

if __name__ == "__main__":
    # Get the database
    dbname = get_database()
    print(f"Connected to database: {dbname.name}")
```

This code connects to a MongoDB server on your computer and uses a database called 'pymongo_tutorial'. If the database doesn't exist, MongoDB will create it when you add data.

Test your connection by running:

```command
python mongo_client.py
```

You should see:

```text
[output]
Connected to database: pymongo_tutorial
```

## Understanding MongoDB Collections

In MongoDB, a collection is where your data lives. If you're coming from a relational database background (like PostgreSQL or MySQL), it's helpful to compare the terminology:

![Diagram comparing SQL and MongoDB concepts. Shows the equivalence between: Database in SQL and Database in MongoDB;](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/a02b06e3-9c8c-4f8e-d97f-c6257bcc1a00/lg1x =2406x792)

| SQL Database | MongoDB    |
|--------------|------------|
| Database     | Database   |
| Table        | Collection |
| Row          | Document   |
| Column       | Field      |

While tables in SQL enforce a fixed schema, collections in MongoDB store flexible, schema-less **documents** written in a JSON-like format, this makes MongoDB great for applications where the structure of your data might evolve over time.

Let’s expand our code to include a function that connects to a specific collection, such as one for storing user data.

Update `mongo_client.py` with the following:

```python
[label mongo_client.py]
from pymongo import MongoClient

def get_database():
    # Connect to MongoDB
    client = MongoClient('mongodb://localhost:27017/')
    
    # Get the database
    return client['pymongo_tutorial']

[highlight]
def get_collection(collection_name):
    # Get the database
    db = get_database()
    
    # Return the requested collection
    return db[collection_name]
[/highlight]

if __name__ == "__main__":
[highlight]
    # Get the users collection
    users_collection = get_collection('users')
    print(f"Connected to collection: {users_collection.name}")
[/highlight]
```

When you run this code, you'll see:
```command
python mongo_client.py
```

```text
[output]
Connected to collection: users
```
This confirms that you’re connected to the `users` collection inside the `pymongo_tutorial` database. MongoDB will automatically create the collection the first time you insert data into it. You're now ready to start adding and retrieving documents.

## Inserting documents into MongoDB

Now that you're connected to your MongoDB collection, let’s insert some data. In MongoDB, data is stored as **documents**, which are essentially Python dictionaries in PyMongo.

Instead of adding insertion logic to your existing file, we’ll create a new script dedicated to inserting users.

Inside your project folder, create a file named `insert_user.py` and add the following code:

```python
[label insert_user.py]
from mongo_client import get_collection

def insert_user(user_data):
    users = get_collection('users')
    result = users.insert_one(user_data)
    print(f"Inserted user with _id: {result.inserted_id}")

if __name__ == "__main__":
    user = {
        "name": "Alice Johnson",
        "email": "alice@example.com",
        "age": 29,
        "is_active": True
    }
    insert_user(user)
```

This script imports the `get_collection()` function from your `mongo_client.py`, gets the `users` collection, and inserts a sample user document.


To insert the user into the database, run:

```command
python insert_user.py
```

You should see something like:

```text
[output]
Inserted user with _id: 6808e09c040f46ab4ae702d8
```

This confirms that the document was successfully added to your MongoDB collection.


## Querying documents from MongoDB

Once you've inserted data into a MongoDB collection, you'll want to retrieve it. PyMongo makes this easy using the `find_one()` and `find()` methods.


To practice this, create a new file called `find_users.py`. 

```python
[label find_users.py]
from mongo_client import get_collection

def find_all_users():
    users = get_collection('users')
    for user in users.find():
        print(user)

def find_user_by_email(email):
    users = get_collection('users')
    user = users.find_one({"email": email})
    print(user)

if __name__ == "__main__":
    print("All users:")
    find_all_users()
    
    print("\nFind by email:")
    find_user_by_email("alice@example.com")
```

In this script, `find_all_users()` loops through all documents in the `users` collection and prints them, while `find_user_by_email()` searches for a specific user based on their email address. 

These basic queries are essential when you need to fetch and display user data from your database.
Run the script:

```command
python find_users.py
```

You’ll see output like:

```text
[output]
All users:
{'_id': ObjectId('6808e09c040f46ab4ae702d8'), 'name': 'Alice Johnson', 'email': 'alice@example.com', 'age': 29, 'is_active': True}

Find by email:
{'_id': ObjectId('6808e09c040f46ab4ae702d8'), 'name': 'Alice Johnson', 'email': 'alice@example.com', 'age': 29, 'is_active': True}
```

You now know how to insert and retrieve documents using PyMongo. Up next, you'll learn how to update existing documents.


## Updating documents in MongoDB

MongoDB allows you to update documents using the `update_one()` or `update_many()` methods. These let you modify fields in one or more documents that match a specific filter.


In this step, you'll create a script to update an existing user's email address in the database. Start by creating a new file named `update_user.py`:

```python
[label update_user.py]
from mongo_client import get_collection

def update_user_email(name, new_email):
    users = get_collection('users')
    result = users.update_one(
        {"name": name},                     # Filter
        {"$set": {"email": new_email}}      # Update operation
    )
    if result.modified_count > 0:
        print(f"Updated email for user '{name}' to {new_email}")
    else:
        print(f"No user found with the name '{name}'")

if __name__ == "__main__":
    update_user_email("Alice Johnson", "alice.johnson@newdomain.com")
```

The script uses `update_one()` to find the first document where the name matches and updates the `email` field using `$set`. 

If a match is found, it confirms the update; otherwise, it lets you know no user was found. This is a common method for updating specific fields in MongoDB without modifying the rest of the document.

```command
python update_user.py
```

```text
[output]
Updated email for user 'Alice Johnson' to alice.johnson@newdomain.com
```

You can confirm the change by running your previous `find_users.py` script again.


## Deleting documents from MongoDB

Sometimes you’ll need to remove documents from a collection—for example, when a user account is deleted or data becomes outdated. PyMongo provides methods like `delete_one()` and `delete_many()` for this.

To try it out, create a new file called `delete_user.py` and add the following:

```python
[label delete_user.py]
from mongo_client import get_collection

def delete_user_by_email(email):
    users = get_collection('users')
    result = users.delete_one({"email": email})
    if result.deleted_count > 0:
        print(f"Deleted user with email: {email}")
    else:
        print(f"No user found with email: {email}")

if __name__ == "__main__":
    delete_user_by_email("alice.johnson@newdomain.com")
```

This script uses `delete_one()` to remove the first document that matches the given email. If no document is found, it prints a message saying so.

To run the script, use:

```command
python delete_user.py
```

You should see:

```text
[output]
Deleted user with email: alice.johnson@newdomain.com
```

You can verify that the document was removed by re-running `find_users.py`.

## Final thoughts
This guide walked you through the basics of using PyMongo with MongoDB in Python. You set up a project, connected to a database, and performed all the key CRUD operations: insert, read, update, and delete. Along the way, you became familiar with how collections and documents work and kept your code organized by using separate scripts.

With these skills, you're ready to build real-world apps or explore advanced features like aggregation and indexing. For more, check out the [official PyMongo docs](https://pymongo.readthedocs.io/).