ImportError: cannot import name 'db' from 'database_functions'

Question:

I’m trying to connect to a Postgres database using Flask and SQLAlchemy.
I followed an youtube tutorial however it doesn’t seem to work for me, as it throws an error normally associated with circular dependencies.

When i type on the Python console: from database_functions import db it says:

Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: cannot import name 'db' from 'database_functions' C:pathtofiledatabase_functions.py)

Here is the code I’m using:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from cryptography.hazmat.primitives import serialization
import psycopg2
import configparser
import jwt
from datetime import datetime

if __name__ == '__main__':
    config = configparser.ConfigParser()
    config.read('database.ini')
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = 'postgresql://'+config['postgresql']['user']+':'+config['postgresql']['password']+'@'+config['postgresql']['host']+':'+config['postgresql']['port']+'/'+'survey_platform'
    db = SQLAlchemy(app)

    class SurveyData(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        codigo_do_projeto = db.Column(db.String(250))

I expected a database file to be created in the same folder as where I’m running the python command.

Asked By: Eduardo Pitta

||

Answers:

This is likely a scoping issue. In your file pasted above, the db variable is not available at the module level since it’s defined inside of an if block.

if __name__ == '__main__': is typically used when you want a file to be directly executable but not have the executable code at the module level.

For example:

# run.py
print("Hello, World!")

versus

# run2.py
if __name__ == "__main__":
    print("Hello, World!")

if you run with python run.py and python run2.py respectively, you’ll see identical results. However, if you create another file which imports either of these as modules, you’d see different results – importing from run2.py won’t print anything but importing run.py will.

# another_file.py
import run
# vs
import run2

so if you want a file to be used like a module and have other modules import [from] it, objects you want to import need to be at the module level, but you should keep in mind that whatever is at the module level will actually execute on import so if you don’t want that to happen, then you should wrap that code into something like if __name__ == '__main__':

To clarify, by "module level", I mean not defined inside of any scope-inducing blocks so basically not indented. If you remove your if and unindent everything within, you should be able to from database_functions import db

Answered By: ccchoy
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.