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.
I have looked at similar questions to this one and haven't found a solution yet. My flask app (a personal website) runs with full functionality on the local server but when I try to run it on the IP address at port 5000 the contactme page (the only page with forms) returns the runtime error in the title. I have my secret key in the directory /etc/config.json and my config.py, __init__.py, and run.py code is below:
run.py
from personalwebsite import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
init.py:
from flask import Flask
from flask_mail import Mail # this package allows us to send an email when the contact form is filled out
from flask_sqlalchemy import SQLAlchemy # Package for our database ORM
from personalwebsite.config import Config
# Instantiate/Create the database
db = SQLAlchemy()
mail = Mail() # Instantiate our Mail object
def create_app(config_class=Config):
app = Flask(__name__) # Instantiate the app
app.config.from_object(Config)
# Imports all routes from the routes.py file
db.init_app(app)
mail.init_app(app)
from personalwebsite.contact.routes import contacts
from personalwebsite.main.routes import main
from personalwebsite.projects.routes import projects
from personalwebsite.resume.routes import resume
app.register_blueprint(contacts)
app.register_blueprint(main)
app.register_blueprint(projects)
app.register_blueprint(resume)
return app
And config.py:
import os
import json
with open('/etc/config.json') as config_file:
config=json.load(config_file)
class Config:
SECRET_KEY = config.get('SECRETKEY')
SQLALCHEMY_DATABASE_URI = "sqlite:///site.db"
MAIL_SERVER = 'smtp.googlemail.com'
MAIL_PORT = 587
MAIL_USE_TLS = True
MAIL_USERNAME = config.get('EMAILUSERNAME')
MAIL_PASSWORD = config.get('EMAILKEY')
I'm not really sure what is wrong here and have been trying to deploy this simple website for the last few days. Any help is appreciated!
I'm trying to run my flask app with "python app.py" instead of "flask run" command.
My goal is to launch the app on cpanel server and just about every tutorial requires the applications to be called using the "python" method.
Here is my folder structure:
project
webapp
init.py
templates
static
auth.py
main.py
app.py <-------------- I want this to be called with python instead of flask run command outside the folder
Here is my init_.py file:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
# init SQLAlchemy so we can use it later in our models
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = '9OLWxND4o83j4iuopO'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
db.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
from .models import User
#login_manager.user_loader
def load_user(user_id):
# since the user_id is just the primary key of our user table, use it in the query for the user
return User.query.get(int(user_id))
# blueprint for auth routes in our app
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
# blueprint for non-auth parts of app
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
And app.py is:
from webapp import app
I'm a newbie in flask, any help is appreciated
Insert the call to create_app at the end of init.py:
if __name__ == '__main__':
create_app().run(host='0.0.0.0', port=5000, debug=True)
The if statement avoid calling the app many times. It can only be called directly. Flask default host is 127.0.0.1 (localhost). Use 0.0.0.0 at production for better traffic monitoring. Default port is also 5000, so it's up to you to include. For better readability, you should explicit it.
Then call it
python webapp/init.py
I am using AWS cloud9 IDE and Python flask to develop a webpage where users can create an account and sign in. However when I run my program I get from flasklab8 import app
File "/home/ec2-user/environment/flasklab8/flasklab8/app/init.py", line 15, in
from flasklab8 import routes
ImportError: cannot import name 'routes'. There are a few other files for this web page but I think this is the only file that is causing the issue if needed I can edit in the rest of the code. I also do not know if this is because I am using AWS. The code for the problem file is below:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
app = Flask(__name__)
app.config['SECRET_KEY'] = '5791628bb0b13ce0c676dfde280ba245'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
from flasklab8 import routes
It looks like your file chain is
/home/ec2-user/environment/flasklab8/flasklab8/app/init.py
Unless you are doing something really strange, you routes.py file should be in your app folder, not your flasklab8, meaning your import statement is incorrect. It should read
from app import routes
I'm creating a Flask server that will display information queried from an sqlite3 database. However, when I try to access the database file after running the localhost, it returns the following error.
File "C:\Users\Connor\Documents\Parking\app\routes.py", line 13, in index
con = sqlite3.connect(app.config['SQLALCHEMY_DATABASE_URI'])
sqlite3.OperationalError: unable to open database file
127.0.0.1 - - [26/Mar/2019 20:30:57] "GET / HTTP/1.1" 500 -
I'm almost positive that the problem stems from sqlite:///, but I can't figure it out. None of the solutions suggested seem to have the answer either.
routes.py
from app import app
from flask import Flask, flash, redirect, request, render_template,
session, url_for
import sqlite3
app.secret_key = app.config['SECRET_KEY']
#app.route('/')
#app.route('/index')
def index():
con = sqlite3.connect(app.config['SQLALCHEMY_DATABASE_URI'])
cur = con.cursor()
cur.execute("SELECT * FROM Lot")
data = cur.fetchall()
return render_template('index.html', data=data)
config.py
import os
PROJECT_ROOT = os.path.dirname(os.path.realpath(__file__))
class Config(object):
SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(PROJECT_ROOT, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
DEBUG = True
SECRET_KEY = 'development key'
init.py
from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
Printing app.config['SQLALCHEMY_DATABASE_URI'] returns sqlite:///C:\Users\Connor\Documents\Parking\app.db. I would assume the forward slashes are the root of my problem. I've tried several variants of os.path but to no avail.
Oddly enough, when I manually type in my path, the database displays just fine AND its data can be manipulated in the admin portal. When I use os.path.join(PROJECT_ROOT, 'app.db'), the database displays, but I can't manipulate its data in the admin portal. When I use "sqlite:///" + os.path.join(PROJECT_ROOT, 'app.db'), I can't access the database at all.
I believe I'm using sqlite:/// correctly as per this document, so maybe I'm just missing something?
The issue here is that you are using the sqlalchemy connection url, but trying to connect directly through the sqlite3 api.
This line of code from within your index() route:
con = sqlite3.connect(app.config['SQLALCHEMY_DATABASE_URI'])
...calls the sqllite3.connect() function, and you are passing that your sqlalchemy connection url: SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(PROJECT_ROOT, 'app.db').
Here is the function signature of sqlite3.connect():
sqlite3.connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri])
And here is an excerpt form the documentation about what can be passed as the database parameter:
database is a path-like object giving the pathname (absolute or
relative to the current working directory) of the database file to be
opened.
sqllite:///some/path/to/app.db is not a valid pathname and that's why the error is raised.
You've gone to all the trouble of configuring flask_sqlalchemy, so you may as well use it!
from app import app, db # <== notice import of db here
from flask import (Flask, flash, redirect, request, render_template,
session, url_for)
app.secret_key = app.config['SECRET_KEY']
#app.route('/')
#app.route('/index')
def index():
data = db.session.execute("SELECT * FROM Lot").fetchall()
return render_template('index.html', data=data)
This has the added bonus of keys included session management that comes with Flask-SQLAlchemy.