SQLAlchemy NameError: Name 'db' is not defined (?) - python

I am working on a Udemy course using flask to record heights. I am at the point where we are using PostgreSQL, and I have it installed, and I have his code copied exactly:
from flask import Flask, render_template, request
from flask.ext.sqlalchemy import SQLAlchemy
app=Flask(__name__)
app.config(['SQLALCHEMY_DATABASE_URI']='postgresql://postgres:password
#localhost/height_collector')
db=SQLAlchemy(app)
class Data(db.Model):
__tablename__='data'
id=db.Column(db.Integer, primary_key=True)
email_=db.Column(db.String(120), unique=True)
height_=db.Column(db.Integer)
def __init__(self, email_, height_):
self.email_=email_
self.height_=height_
#app.route("/")
def index():
return render_template("index.html")
#app.route("/success", methods=["post"])
def success():
if request.method=='POST':
email=request.form['email_name']
height=request.form['height_name']
print(height,email)
return render_template("success.html")
if __name__=='__main__':
app.debug=True
app.run()
Problem comes into play, when he says to run python in a virtual env, and then enter :db.create_all() to create a database in PostgreSQL and I get this error :
File <'stdin'>, line 1 in
NameError: Name 'db' is not defined
Not sure how to proceed, any input would be appreciated.

you can make a db.py where you can store the code db = SQLAlchemy(). Then import in in app.py. now you can able to call db. or just remove APP in db=SQLAlchemy(app)

I think you probably need to run some of the other code first so that you define db and your table schema. Then you can run db.create_all().
from flask import Flask, render_template, request
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config(['SQLALCHEMY_DATABASE_URI'] =
'postgresql://postgres:password#localhost/height_collector')
db = SQLAlchemy(app)
class Data(db.Model):
__tablename__ = 'data'
id = db.Column(db.Integer, primary_key=True)
email_ = db.Column(db.String(120), unique=True)
height_ = db.Column(db.Integer)
def __init__(self, email_, height_):
self.email_ = email_
self.height_ = height_
db.create_all()

I just faced this error and it is because I didn't import db before calling the db function. If you're running in terminal, 'from yourappname import db' and any other functions you are running.
//IN TERMINAL
from yourappname import db

Start python shell by running the command python. Then import db to define it:
from main import db
db.drop_all()
db.create_all()

You need to set the FLASK env variable.
create a .flaskenv file in the top directory of your project
Add this to your .flaskenv file:
export FLASK_APP=myappfile.py
Install dotenv to your environment
pip install python-dotenv
Now if you run the app it should pick up your env variable.

Type the Following and it will work:
cd flask-app
venv\scripts\activate
python3
from app import db
db.create_all()

Related

How to use instance file in flask

I am using SQLalchemy to create my db in flask. For this I create a project.db file and run the following code :
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# create the extension
db = SQLAlchemy()
# create the app
app = Flask(__name__)
# configure the SQLite database, relative to the app instance folder
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"
# initialize the app with the extension
db.init_app(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, unique=True, nullable=False)
email = db.Column(db.String)
with app.app_context():
db.create_all()
When I run create_table, it creates me a new folder named instance and a new project.db file in it. The result is that my first project.db does not work and is useless.
What must I do then ? Because when looking at different topic and videos this never happens. Thanks in advance !
Where is project.db located? Keep it in the same folder as the script, or try using an absolute path like this?
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////absolute/path/to/project.db"

Flask_SQLAlchemy modularization issues due ORM

I am trying to build an API using Flask. For database actions I use flask_sqlalchemy.
In my main file, the flask app is initalized. I pass the resulting instance to another file where the configuration is set and to my database module that handles database operations.
main.py:
app = flask.Flask(__name__) # initialize flask app
#initialize modules with app
config.init(app)
database.init(app)
The problem is, the relations I use in the database are in a seperate file and it needs the db object to declare the classes for ORM.
My idea was to declare db and initialize it later in an init function, but that doesn't work in this case, because the db object is undefined when the pythonfile is loaded by an import.
relations.py
db: SQLAlchemy
def init(db):
Relations.db = db
class Series(db.Model):
"""Representation of a series
"""
id = db.Column(db.String(255), primary_key=True)
title = db.Column(db.String(255))
class User(db.Model):
"""Representation of a user
"""
id = db.Column(db.INT, primary_key=True)
name = db.Column(db.String(255))
class Subscription(db.Model):
"""Representation of a subscription
"""
series_id = db.Column(db.INT, primary_key=True)
user_id = db.Column(db.String(255), primary_key=True)
My database module uses the way and it works fine(init.py file):
db: SQLAlchemy
def init(app):
database.db = SQLAlchemy(app)
# handle database operations...
One approach to solve the issue is just using another instance in the relations.py like that:
app = flask.Flask(__name__)
db = SQLAlchemy(app)
# declare classes...
I tried it out and it workes, but that is not a nice way to solve this and leads to other problems.
Importing it from main does also not work because of circular import.
I have no idea how to smoothly solve this without removing modularization. I would be thankful for any inputs. If I should add any further information, just let me know.
I would create the app variable in your main.py file but leave out the initializing part. From there you call a function from init.py to basically set up the database. That is what I did for my last flask project.
Main.py:
from init import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
Init.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
DB_NAME = "database.db"
def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
create_database(app)
#Other operations ...
return app
Relations.py
from init import db
#all your classes ...
db.create_all()
So now you can import the db object to your relations.py file from the init.py.

Python Flask Postgres error - Can't generate DDL for NullType(); did you forget to specify a type on this Column?

Seemingly out of the blue I started getting this error whenever I try to run my flask app.
Can't generate DDL for NullType(); did you forget to specify a type on this Column?
I've changed nothing with the code or database. It runs fine from another server so I'm thinking it has to be something with the computer I'm running the script on but I'm out of ideas. I restarted my computer, restarted the database. Here is the code
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:password#ngdeva-2/flaskapp2'
db = SQLAlchemy(app)
class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
wmx_jobid = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"{self.id} - {self.wmx_jobid}"
db.create_all()
#app.route('/', methods=['GET'])
def home():
message = 'Flask is UP and RUNNING!'
return jsonify(message)
if __name__ == "__main__":
from waitress import serve
serve(app, host="0.0.0.0", port=8080)
Something must have been jacked up with my Python venv. I deleted/recreated the venv and that fixed the problem.

Registering sqlalchemy extension with current application using init_app()

I'm trying to run an existing app in a new environment. The app ran fine in a previous environment, but when I run it locally it refuses to connect with my DB.
AssertionError: The sqlalchemy extension was not registered to the current application. Please make sure to call init_app() first.
Where I'm confused is that this exact code worked in a previous environment. It's asking me to call init_app() but, from my understanding, that's only if there are multiple apps, which there aren't.
In debugging mode, the app does recognize the object i.e.
>>> type(Candidate)
<class 'flask_sqlalchemy.model.DefaultMeta'>
I am unclear how and where to incorporate app_init() into my code. I have tried...
db = SQLAlchemy(app)
db.init_app(app)
but this didn't have any impact.
Folder structure...
app
- static folder
- templates folder
- _init_.py
- config.py
- views.py
- run.py
- Procfile
You could try following code and structure in init.py
db = SQLAlchemy()
def create_app():
app = Flask()
db.init_app(app)
from user_model import User
with app.app_context():
db.create_all()
The problem was that there was legacy code that was supposed to be removed. I was initializing an app twice by accident.
Instead of creating init.py, why don't you import db directly from models
The code below shows my models.py with table students
from flask import Flask,session
from flask_sqlalchemy import SQLAlchemy
#initialize this two objects below app and db parameters so that app.py will have the same db session.
#then in app.py add from models import db
#finally add db.init_app(app) at the bottom of app.py or run.py
app = Flask(__name__)
db = SQLAlchemy(app)
class Students(db.Model):
id = db.Column('student_id', db.Integer, primary_key = True)
name = db.Column(db.String(50))
email = db.Column(db.String(50))
def __repr__(self):
return '<Student {}>'.format(self.email)
Then in your app.py or run.py
You will have to make an import for db
from models import db
Your assertion error for sql-alchemy can be mitigate by moving the two following line of code
immediately after this line of code towards the bottom
if __name__ == '__main__':
hence the code will become like below and your application will run without issue
if __name__ == '__main__':
#create table
db.create_all()
db.init_app(app)
# remember to turn app debug by setting it to false in production
app.run(debug=True)

Creating a database in flask sqlalchemy

I'm building a Flask app with Flask-SQLAlchemy and I'm trying to write a script that will create a Sqlite3 database without running the main application. In order to avoid circular references, I've initialized the main Flask app object and the SQLAlchemy database object in separate modules. I then import and combine them in a third file when running the app. This works fine when I'm running the app, as the database is built and operates properly when create rows and query them. However, when I try to import them in another module, I get the following error:
RuntimeError: application not registered on db instance and no applicationbound to current context
My code looks like the following:
root/create_database.py
from application.database import db
from application.server import app
db.init_app(app)
db.create_all()
root/run.sh
export FLASK_APP=application/server.py
flask run
root/application/init.py
from database import db
from server import app
db.init_app(app)
from routes import apply_routes
apply_routes(app)
root/application/database.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
root/application/server.py
from flask import Flask
import os
app = Flask(__name__)
path = os.path.dirname( os.path.realpath(__file__) )
database_path = os.path.join(path, '../mydb.sqlite')
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + database_path
root/application/models/init.py
from user import User
root/application/models/user.py
from application.database import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
password = db.Column(db.String(120))
def __init__(self, username, password):
self.username = username
self.password = password
In my create_database.py script I'm trying to make sure that the SQLAlchemy db instance is configured with the config details from the app object, but it doesn't seem to be connecting for some reason. Am I missing something important here?
You either have to create a request or you have to create the models with sqlalchemy directly. We do something similar at work and chose the former.
Flask lets you create a test request to initialize an app. Try something like
from application.database import db
from application.server import app
with app.test_request_context():
db.init_app(app)
db.create_all()

Categories