Changing from localhost to atlas - TypeError: 'NoneType' object is not subscriptable (python, flask)

I am making a flask application and used the localhost mongodb in the beginning.
To make my app a step further to deployment i migrated from a localhost db to an atlas cluster. I did setup my atlas cluster, exported all the local documents with compass and uploaded them to the new atlas cluster. With the connect button I got my connection string for the python application and replaced my current one for the localhost db with the one for the atlas db. (in the flask project)

After a reboot of my app, as soon as I try to retrieve data, I get an TypeError: 'NoneType' object is not subscriptable. After changing the conncetion string back to localhost everything works as excpected.

The connection-strings look as follows:
localhost: mongodb://localhost:27017/BM_MaGru
atlas: mongodb+srv://<my_actual_username>:<my_actual_pasword>@nl-bm-ma-gru-001.lne5lsy.mongodb.net/?retryWrites=true&w=majority&appName=nl-bm-ma-gru-001

My local db is called “BM_MaGru” and the atlas db is called “nl-bm-ma-gru-001”. I can obviously see that there is a difference in the name of these dbs. Because of the use of flask-pymongo/pymongo I never had to specify a db name, so I expect it to work automatic. (?)

Is there something else I have to change when I change the db from a local to an atlas cluster?

Hi @Ciril_S,

I’m having to make a few guesses, because you haven’t provided any code.

My main guess is that you’re using get_default_database - is that correct? I notice that your first connection string includes a default database name, but your Atlas connection string does not. (appName is not the same thing as your database name. Adding a database name to your Atlas connection string would look like this:

mongodb+srv://<my_actual_username>:<my_actual_pasword>@nl-bm-ma-gru-001.lne5lsy.mongodb.net/YOURDATABASENAME?retryWrites=true&w=majority&appName=nl-bm-ma-gru-001

If you’re not using get_default_database then I’m going to need you to provide the lines of code that you’re using to get your client, database, and collection, so that I can see what’s going on.

Hope this helps!

Mark

Thanks a lot @Mark_Smith !!!

I indeed use the get_default_database (but more or less by accident, just by not knowing more about it). Adding the name of the db where you mentioned it did solve my problem, thanks a lot! :heart:


Follow up question because I to use get_default_database:

At the moment i “create” the db in the code in the following files like this:

database.py :

from flask_pymongo import PyMongo

mongo = PyMongo()

__init__.py :

from .database import mongo

def init_app():
    mongo.init_app(app)

and later in the code, if I want to access the db:

from src.database import mongo

def db_functio():
    collection = mongo.db['collection_name']

    var = collection.find_one({},{})

according to:
https://pymongo.readthedocs.io/en/stable/tutorial.html

i can specify the db for the object with

from pymongo import MongoClient

client = MongoClient()

client = MongoClient("mongodb://localhost:27017/")

db = client["test-database"]
  1. Is my current way of setting up the db with mongo = PyMongo() not good and/or why should i use client = MongoClient() instead of mongo = PyMongo()?
  2. Could i create multiple dbs with variations of the last line of the tutorial?
    (like this:)
db_1 = client["test-database_1"]

db_2 = client["test-database_2"]

db_3 = client["test-database_3"]

Sorry for pulling you in, into my followup question. But thanks in advance for your time and your reply. :heart:

Hey!

PyMongo is provided by flask_pymongo which specifically adapts PyMongo to Flask. It makes MongoDB more easily available to your view functions and provides some extra helper methods like find_one_or_404. It’s probably fine to continue using it unless it causes you problems.

As well as setting the database as a db attribute, flask-pymongo also sets cx to point to a pymongo.MongoClient which can be used to access any database you want within the cluster. I recommend using get_database and get_collection methods instead of using the [name] syntax:

def db_function():
    client = mongo.cx
    database_1 = client.get_database("test-database_1")
    collection = database_1.get_collection("my_collection")

Using the array lookup on a client or database or collection can get confusing because it’s easy to accidentally try to lookup a collection on another collection (which works but gives you something weird!) or to look up a collection on a client, which will give you a database by mistake. If you use the explicit methods, you at least know what you’re going to get :slight_smile:

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