sqlalchemy.create_all() got an unexpected keyword argument 'app' [duplicate] - python

I'm following a tutorial for creating a Flask app with Flask-SQLAlchemy. However, it has started raising an error when creating the database. How do I create the database?
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"
db.init_app(app)
from . import models
create_database(app)
return app
def create_database(app):
if not path.exists("website/project.db"):
db.create_all(app=app)
print("created database")
The line db.create_all(app=app) gives me this error:
SQLAlchemy.create_all() got an unexpected keyword argument 'app'

Flask-SQLAlchemy 3 no longer accepts an app argument to methods like create_all. Instead, it always requires an active Flask application context.
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"
db.init_app(app)
from . import models
with app.app_context():
db.create_all()
return app
There is no need for that create_database function. SQLAlchemy will already not overwrite an existing file, and the only time the database wouldn't be created is if it raised an error.

Related

Flask-Pymongo DB is returning as None

I am trying create a webapp with Flask-Pymongo, but it is saying that my database does not exist.
This is my __init__.py:
import os
from flask import Flask
from flask_pymongo import PyMongo
mongo = PyMongo()
def init_app():
app = Flask(__name__)
app.config.from_pyfile('config.py')
mongo.init_app(app)
with app.app_context():
from temp.routes.stage_routes import stage_route
app.register_blueprint(stage_route)
return app
This is my db.py (temp is the top level directory)
from temp.__init__ import mongo
db = mongo.db
and this is one of my blueprints with routes to query the database
from flask import Blueprint
from temp.db import db
stage_route = Blueprint('stage_route', __name__, url_prefix='/stages')
#stage_route.route('/')
def home():
return 'This is the home page for the stage blueprint'
#stage_route.route('/all')
def all():
stage = db.stages.find() # This is where the error is
print(stage)
For some reason I get the error saying that "NoneType does not have attribute 'stages'" because it is saying that the db variable is none. I can't figure out why this is is happening since the database and the collection does exist and the MONGO_URI string is loaded from the config file. I can see that it is connecting on the mongodb side, but i'm assuming it has something to do with my create_app() function in the init.py file. Do you see something that I am missing? Any help would be appreciated
The code is missing the connection URI string, as mentioned in the documentation -
from flask import Flask
from flask_pymongo import PyMongo
app = Flask(__name__)
# The missing URI
app.config["MONGO_URI"] = "mongodb://localhost:27017/myDatabase"
mongo = PyMongo(app)

How can I get a flask config attribute in a model that is not in the app context?

I put the SQLAlchemy object into the model.py:
db = SQLAlchemy()
And then import and use it in the app.py:
def create_app(config_filename):
app = Flask(__name__)
app.config.from_mapping(DEBUG=True)
from yourapplication.model import db
db.init_app(app)
However, if I need to add a session option, say autoflush, to the SQLAlchemy, and the option value is from the app object, say app.debug:
autoflush = app.debug
db = SQLAlchemy(session_options={'autoflush': autoflush})
How can I achieve this? I can't use the app.app_context or the g object because they aren't in app context, and I also don't want to create a new app instantiation here.

What should I do with SQLAlchemy NameError: Name 'db' is not defined

I am building a web app with Flask and SQLAlchemy. I can't seem to find out the reason for this error NameError: name'db' is not defined Would really appreciate your help.
from flask import Flask, render_template
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
db=SQLAlchemy()
app=Flask(__name__)
#create a function that creates a web application
# a web server will run this web application
def create_app():
app.debug=True
app.secret_key='BetterSecretNeeded123'
#set the app configuration data
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///bcib.sqlite'
#initialize db with flask app
db.init_app(app)
bootstrap = Bootstrap(app)
#importing modules here to avoid circular references, register blueprints of routes
from . import views
app.register_blueprint(views.bp)
#from . import admin
#app.register_blueprint(admin.bp)
return app
#app.errorhandler(404)
# inbuilt function which takes error as parameter
def not_found(e):
return render_template("404.html")
#app.errorhandler(500)
def internal_error(e):
return render_template("500.html")
When I try to input db.session.add(c1) in my terminal the error occurs
File "<stdin>", line 1, in <module>
NameError: name 'db' is not defined
Here the specific documentation : flask documentation
There is two ways to init the db :
you can binding the instance to a very specific Flask application like this
app = Flask(__name__)
db = SQLAlchemy(app)
you can create the object once and configure the application later to support :
db = SQLAlchemy()
def create_app():
*/
* Your code
/*
db = SQLAlchemy(app)
db.init_app(app) # HERE you need to call an init_app
return app
so in your case the best way is the second solution with the add of
db.init_app(app)
if you choose this solution, it will work normally.

How to define and access the database postgresql like flask sample code

I'm new use python flask, I want connected to postgresql use code like flask sample in this link, but in code sample use sqlite3. I try to search code sample and make me confused because every sample use different approach. This my code run but when use CLI to initialize database error.
Error: No such command "init-db".
My structure file
This my code:
run.py
#run.py
import os
from smart_app import create_app
app = create_app()
if __name__ == '__main__':
app.run()
init.py
#__init__.py
from flask import Flask
def create_app(config_filename=None):
app = Flask(__name__, instance_relative_config=True)
# load default configuration
app.config.from_object('config.default')
# load the configuration from the instance folder
app.config.from_pyfile('config.py')
# Load the file specified by the APP_CONFIG_FILE environment variable
# Variables defined here will override those in the default configuration
app.config.from_envvar('APP_CONFIG_FILE')
# Connect to database
from . import db
db.init_app(app)
return app
db.py
db.py
import click
from flask import current_app, g
from flask.cli import with_appcontext
from flask_sqlalchemy import SQLAlchemy
# db = SQLAlchemy()
def get_db():
if 'db' not in g:
g.db = SQLAlchemy()
return g.db
def close_db(e=None):
db = g.pop('db', None)
if db is not None:
db.close()
def init_db():
db = get_db()
with current_app.open_resource('schema.sql') as f:
db.executescript(f.read().decode('utf8'))
#click.command('init-db')
#with_appcontext
def init_db_command():
"""Clear the existing data and create new tables."""
init_db()
click.echo('Initialized the database')
def init_app(app):
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)
If you familiar with SQL, use the psycopg2 to connect to your postgresql database.
Or if you want use ORM to operate the database in flask, you can use flask_sqlalchemy.

Access to Flask Global Variables in Blueprint Apps

my source code has this structure:
main.py:
from flask import Flask, g
app = Flask(__name__)
with app.app_context():
g.my_db = PostgreSQL()
app.register_blueprint(my_app, url_prefix="/my_app")
my_app.py:
from flask import Blueprint, g
my_app = Blueprint("my_app", __name__)
#my_app.route("/")
def index():
return g.my_db.fetch_all() <<< ERROR
but it shows this error:
AttributeError: '_AppCtxGlobals' object has no attribute 'my_db'
Even when I try to use g outside of app context, it shows this error:
RuntimeError: Working outside of application context.
So how to set and access to global variables in Flask?
This happens because the data are lost when the context (with app.app_context()) ends (doc).
Inside the context, everything is ok :
from flask import Flask, g
app = Flask(__name__)
with app.app_context():
g.my_db = 'database ok'
print(g.my_db)
# >>> this prints 'database ok'
But outside, you cannot access the attribute :
from flask import Flask, g
app = Flask(__name__)
with app.app_context():
g.my_db = 'database ok'
print(g.my_db)
# >>> this throws RuntimeError: Working outside of application context
even if you create a new context:
from flask import Flask, g
app = Flask(__name__)
with app.app_context():
g.my_db = 'database ok'
with app.app_context():
print(g.my_db)
>>> this throws AttributeError: '_AppCtxGlobals' object has no attribute 'my_db'
Your best call should be to declare the database object before the context, and then import it. Or maybe you can create it directly inside my_app.py where you need it ?
g isn't persistent in the way you're trying to use it. Write a function to create a connection each time you need it. Preferably use a database extension like Flask-SQLAlchemy to manage connections for you.
db.py:
import <postgresql dependencies>
def get_db():
db = PostgreSQL()
# config here
return db
main.py:
from flask import Flask
app = Flask(__name__)
app.register_blueprint(my_app, url_prefix="/my_app")
my_app.py:
from flask import Blueprint, g
from db import get_db
my_app = Blueprint("my_app", __name__)
#my_app.route("/")
def index():
db = get_db()
data = db.fetch_all()
db.close()
return data

Categories