SQLALCHEMY_DATABASE_URI not set - python-3.x

I tried to work with CURD operation using Flask and SQLAlchemy.But getting Error while connecting to database.
Here is the Error log.
/usr/local/lib/python3.4/dist-packages/flask_sqlalchemy/__init__.py:819: UserWarning: SQLALCHEMY_DATABASE_URI not set. Defaulting to "sqlite:///:memory:".
'SQLALCHEMY_DATABASE_URI not set. Defaulting to '
/usr/local/lib/python3.4/dist-packages/flask_sqlalchemy/__init__.py:839: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
here is my code & setup
# database.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
sqldb = SQLAlchemy(app)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:root#localhost/myDbName"
# create app
def create_app():
sqlDB = SQLAlchemy(app)
sqlDB.init_app(app)
sqlDB.create_all()
return app
here is models.py
from ..database import create_app
sqldb = create_app()
# Users Model
class Users(sqldb.Model):
__tablename__ = 'users'
id = sqldb.Column(sqldb.Integer, primary_key = True)
db = sqldb.Column(sqldb.String(40))
def __init__(self,email,db):
self.email = email
self.db = db
def __repr__(self,db):
return '<USER %r>' % self.db
here is routes.py
# Import __init__ file
from __init__ import app
import sys
# JSON
from bson import dumps
# login
#app.route('/', methods = ['GET'])
def login():
try:
# import users model
from Model.models import Users,sqldb
sqldb.init_app(app)
sqldb.create_all()
getUser = Users.query.all()
print(getUser)
return 'dsf'
except Exception as e:
print(e)
return "error."

You probably need to put this line app.config['SQLALCHEMY_DATABASE_URI'] = "mysql..." before the SQLAlchemy(app) instanciation.
Another option is to create SQLAlchemy() without parametters, to configure URI, and finally to tell SQLAlchemy to link with your app via sqldb.init_app(app)
Note that it is what you've done in your create_app function, but you never use it ?

Like the answer above, if you use it this way, change
sqldb = SQLAlchemy(app)
to
sqldb = SQLAlchemy()

I got the same error, and it was gone after setting the FLASK_APP environment variable :
export FLASK_APP=run.py
Start the application :
flask run --host=0.0.0.0 --port=5000

This type of error occurs when app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] is not set. You can set it as True or False like so:
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
or
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

Your method create_app returning a Flask() object called app
In the models.py module your variable sqldb should be pointing to sqlDB from code&setup file

Related

Connecting to ready Azure Database with Flask and SQLAlchemy, getting app context error

I have this code that is trying to connect to a user table in a database:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import yaml
db_info = yaml.safe_load(open('db.yaml'))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mssql+pyodbc://{dbuser}:{dbpass}#{server}.database.windows.net/{' \
'dbname}?driver=ODBC+Driver+17+for+SQL+Server'.format(
dbuser=db_info['user'],
dbpass=db_info['password'],
server=db_info['server'],
dbname=db_info['name']
)
db = SQLAlchemy(app)
class Users(db.Model):
ID = db.Column(db.Integer, primary_key=True, nullable=False)
UserName = db.Column(db.Text)
PhoneNum = db.Column(db.Text)
Password = db.Column(db.Text)
YearOfStudy = db.Column(db.Integer)
def __repr__(self):
return '<User %r>' % self.ID
#app.route('/')
def hello_world(): # put application's code here
print(Users.query.all())
return "Hello World"
if __name__ == '__main__':
app.run()
However when I run it, the link generated by the flask application doesn't load and the program terminates from timing out.
I did some debugging and saw that Users.query call results in an error as such:
Working outside of application context.
This typically means that you attempted to use functionality that needed
the current application. To solve this, set up an application context
with app.app_context(). See the documentation for more information.
I tried using with app.app_context to run the program by using code as such:
def __repr__(self):
return '<User %r>' % self.username
if __name__ == '__main__':
with app.app_context():
print(User.query.all())
But it didn't work. I also tried doing this:
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mssql+pyodbc://{dbuser}:{dbpass}#{server}.database.windows.net/{' \
'dbname}?driver=ODBC+Driver+17+for+SQL+Server'.format(
dbuser=db_info['user'],
dbpass=db_info['password'],
server=db_info['server'],
dbname=db_info['name']
)
db.init_app(app)
return app
app = create_app()
...
...
if __name__ == '__main__':
app.run()
Which had moderate success but the queries for User.query.all() still don't show, and filter_by() functions don't work either.
I also cannot use db.create_all() as this is a ready database, so I can't wipe the database I'm working on

UserWarning: Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. Defaulting SQLALCHEMY_DATABASE_URI to "sqlite:///:memory:"

I have been trying to solve an issue related to SQLALCHEMY in Flask as my db is not getting created even though I set the SQLACHEMY_DATABASE_URI to "app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'".
In the warning it says the 'sqlite:///:memory:'. When db.create_all() is call test.sql file is not created and also in the UI I see errors as mentioned bellow:
Instance of 'SQLAlchemy' has no 'Column' memberpylint(no-member) and 3 others
Please help in resolving this issue and generating the db and SQL file.
from flask import Flask, render_template, url_for
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
#Initializing database
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
#Creating model
class Todo(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(200), nullable=False)
completed = db.Column(db.Integer, default=0)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<Task %r>' % self.id
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)

How to connect to flask-sqlalchemy database from inside a RQ job

Using flask-sqlalchemy, how is it possible to connect to a database from within a redis task?
The database connection is created in create_app with:
db = SQLAlchemy(app)
I call a job from a route:
#app.route("/record_occurrences")
def query_library():
job = queue.enqueue(ApiQueryService(word), word)
Then inside the redis task, I want to make an update to the database
class ApiQueryService(object):
def __init__(self,word):
resp = call_api()
db.session.query(Model).filter_by(id=word.id).update({"count":resp[1]})
I can't find a way to access the db. I've tried importing it with from app import db. I tried storing it in g. I tried reinstantiating it with SQLAlchemy(app), and several other things, but none of these work. When I was using sqlite, all of this worked, and I could easily connect to the db from any module with a get_db method that simply called sqlite3.connect(). Is there some simple way to access it with SQLAlchemy that's similar to that?
This can be solved using the App Factory pattern, as mentioned by #vulpxn.
Let's assume we have our configuration class somewhere like this:
class Config(object):
DEBUG = False
TESTING = False
DEVELOPMENT = False
API_PAGINATION = 10
PROPAGATE_EXCEPTIONS = True # needed due to Flask-Restful not passing them up
SQLALCHEMY_TRACK_MODIFICATIONS = False # ref: https://stackoverflow.com/questions/33738467/how-do-i-know-if-i-can-disable-sqlalchemy-track-modifications/33790196#33790196
class ProductionConfig(Config):
CSRF_COOKIE_SAMESITE = 'Strict'
SESSION_PROTECTION = "strong"
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Strict'
SECRET_KEY = "super-secret"
INVITES_SECRET = "super-secret"
PASSWORD_RESET_SECRET = "super-secret"
PUBLIC_VALIDATION_SECRET = "super-secret"
FRONTEND_SERVER_URL = "https://127.0.0.1:4999"
SQLALCHEMY_DATABASE_URI = "sqlite:///%s" % os.path.join(os.path.abspath(os.path.dirname(__file__)), "..",
"people.db")
We create our app factory:
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
from development.config import DevelopmentConfig
from rq import Queue
from email_queue.worker import conn
db = SQLAlchemy()
q = Queue(connection=conn)
def init_app(config=ProductionConfig):
# app creation
app = Flask(__name__)
app.config.from_object(config)
# plugin initialization
db.init_app(app)
with app.app_context():
# adding blueprints
from .blueprints import api
app.register_blueprint(api, url_prefix='/api/v1')
return app
We will now be able to start our app using the app factory:
app = centrifuga4.init_app()
if __name__ == "__main__":
with app.app_context():
app.run()
But we will also be able to (in our Redis job), do the following:
def my_job():
app = init_app()
with app.app_context():
return something_using_sqlalchemy()

Basic Flask SQLAlchemy Context Issue

I've read many of the other posts on having models separated from the main app but I can't get it to work with just app.py (my actual app) and models.py (my database models).
If I do the following I get an app.db file with no tables:
from app import db
db.create_all()
If I do the following I get a RuntimeError: No application found. Either work inside a view function or push an application context.:
from app import db
db.create_all()
I have also looked at Introduction into Contexts page and can't work out where I put def create_app():, none of it seemed to work in my case.
Here is my app.py:
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
from models import userTable
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
#app.route('/', methods=['GET', 'POST'])
def home():
return "home"
if __name__ == '__main__':
app.run(debug=True)
Here is my models.py:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class userTable(db.Model):
__tablename__ = "userTable"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
Perhaps you could try the following:
app.py
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
import models
from models import initialize_db
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
initialize_db(app)
#app.route('/', methods=['GET', 'POST'])
def home():
return "home"
if __name__ == '__main__':
app.run(debug=True)
models.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def initialize_db(app):
app.app_context().push()
db.init_app(app)
db.create_all()
class userTable(db.Model):
__tablename__ = "userTable"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
The key is creating a database initialization function within models.py which takes the application instance as a parameter. This function only creates the database tables once it has its application instance. This will allow you to import the models module initially without an application instance and still have a modular design.

SQLAchemy 'No application found. Either work inside a view function or push'

Ello ello,
I found similar questions on the bug i'm facing, and tried the solutions offered but it didn't work for me.
I'm trying to separate out my models in a different directory and import them into the app.py
When I try to import the db into the python terminal, i'm getting the no application found.
app.py code
from flask import Flask
from flask_restful import Resource, Api
# from flask_sqlalchemy import SQLAlchemy
from routes import test, root, user
from models.todo import db
app = Flask(__name__)
api = Api(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://username:pass123#localhost/db'
app.config['SECRET_KEY'] = 'thiskeyissecret'
# db.init_app(app)
with app.app_context():
api = Api(app)
db.init_app(app)
api.add_resource(root.HelloWorld, '/')
api.add_resource(test.Test, '/test')
api.add_resource(user.User, '/user')
if __name__ == '__main__':
app.run(debug=True)
models
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Todo(db.Model):
__tablename__ = 'Todos'
id = db.Column('id', db.Integer, primary_key=True)
data = db.Column('data', db.Unicode)
def __init__(self, id, data):
self.id = id
self.data = data
def __repr__(self):
return '<Todo %>' % self.id
my file directory looks like
Main_app
Models
Todo.py
routes
some routes
app.py
Flask-SQLAlchemy needs an active application context.
Try:
with app.app_context():
print(Todo.query.count())
From the flask documentation:
Purpose of the Context
The Flask application object has attributes, such as config, that are
useful to access within views and CLI commands. However, importing the
app instance within the modules in your project is prone to circular
import issues. When using the app factory pattern or writing reusable
blueprints or extensions there won’t be an app instance to import at
all.
Flask solves this issue with the application context. Rather than
referring to an app directly, you use the the current_app proxy, which
points to the application handling the current activity.
Flask automatically pushes an application context when handling a
request. View functions, error handlers, and other functions that run
during a request will have access to current_app.
It is ok to have db initialised in app.py
from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
from routes import test, root, user
app = Flask(__name__)
api = Api(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://username:pass123#localhost/db'
app.config['SECRET_KEY'] = 'thiskeyissecret'
db = SQLAlchemy(app)
api.add_resource(root.HelloWorld, '/')
api.add_resource(test.Test, '/test')
api.add_resource(user.User, '/user')
if __name__ == '__main__':
app.run(debug=True)
Then in your todo.py
from app import db
class Todo(db.Model):
__tablename__ = 'Todos'
id = db.Column('id', db.Integer, primary_key=True)
data = db.Column('data', db.Unicode)
def __init__(self, id, data):
self.id = id
self.data = data
def __repr__(self):
return '<Todo %>' % self.id
I get a same err
that err reason for just can operation db in viewfunc
def __init__(self, id, data):
self.id = id
self.data = data
try move that code operation to your viewfunc
In a nutshell, do something like this:
from yourapp import create_app
app = create_app()
app.app_context().push()

Resources