I started a simple Flask project, i'm using SLQAlchemy to handle my Database. My problem is that every time i run my app, i'll get the following error:
File "C:\Users\user\AppData\Local\Programs\Python\Python38\lib\site-packages\flask_sqlalchemy\__init__.py", line 137, in __init__
track_modifications = app.config['SQLALCHEMY_TRACK_MODIFICATIONS']
KeyError: 'SQLALCHEMY_TRACK_MODIFICATIONS'
Here is my code:
from flask import Flask, request, jsonify
import json
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String
from sqlalchemy.schema import FetchedValue
app = Flask(__name__)
db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'users'
__table_args__ = {'schema': 'tvtg'}
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(350), nullable=False)
email = db.Column(db.String(350), nullable=False)
password = db.Column(db.String(350), nullable=False)
#app.route('/')
def hello_world():
print('HERE')
peter = User.query.filter_by(name='peter').first()
print(peter)
return 'hello_world'
if __name__ == "__main__":
app.run()
Can anyone help me find what i'm doing wrong? The traceback of the error is not helping me much
Actually, it looks like when using flask-sqlalchemy, you have to set a value for SQLALCHEMY_TRACK_MODIFICATIONS - even the documentation says otherwise (defaults to None).
Whether you want to set it to True or False is up to your use case, see documentation
https://flask-sqlalchemy.palletsprojects.com/en/2.x/config/
Or have a look at this great tutorial
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-iv-database
The unreleased Flask-Sqlalchemy version 3 sets a new default of False.
Related
I'm trying to test Flask with SQLAlchemy and I stumbeld accross this problem. First, I have to note that I read all of the related threads and none of them solves my problem. I have a problem that db.create_all() doesn't generate the table I defined. I have model class in file person.py:
from website import db
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, nullable=False)
password = db.Column(db.String)
width = db.Column(db.Integer)
height = db.Column(db.Integer)
agent = db.Column(db.String)
user_data_dir = db.Column(db.String)
And in my website.py which is the file from where I launch the app:
from flask import Flask, jsonify, render_template, request
from flask_sqlalchemy import SQLAlchemy
# create the extension
db = SQLAlchemy()
def start_server(host, port, debug=False):
from person import Person
# create the app
app = Flask(__name__,
static_url_path='',
static_folder='web/static',
template_folder='web/templates')
# configure the SQLite database, relative to the app instance folder
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database0.db"
# initialize the app with the extension
db.init_app(app)
print('initialized db')
print('creating tables...')
with app.app_context():
db.create_all()
db.session.add(Person(username="example33"))
db.session.commit()
person = db.session.execute(db.select(Person)).scalar()
print('persons')
print(person.username)
if __name__ == '__main__':
start_server(host='0.0.0.0', port=5002, debug=True)
I think the problem might be that the Person class is not importing properly, because when I put the class inside the start_server function it executes fine and creates the table, but I don't know why this is happening. I followed all the advice and imported it before everything, and also I share the same db object between the 2 files
There is probably a better way to do this but this is the only way I could get this to work. You need to create a models.py file or w.e you wanna call it. Then all your database stuff goes in there. The db engine, ALL your models and a function to initialize it all. The reason is, you are having import issues where Person is imported but not fully and so the db doesn't have it in its metadata.
models.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, nullable=False)
password = db.Column(db.String)
width = db.Column(db.Integer)
height = db.Column(db.Integer)
agent = db.Column(db.String)
user_data_dir = db.Column(db.String)
# All other models
def initialize_db(app: Flask):
db.init_app(app)
with app.app_context():
db.create_all()
main.py
from flask import Flask
import models
def start_server(host, port, debug=False):
app = Flask(__name__)
# configure the SQLite database, relative to the app instance folder
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database0.db"
# initialize the app with the extension
models.initialize_db(app)
db = models.db
with app.app_context():
db.session.add(models.Person(username="example33"))
db.session.commit()
person = db.session.execute(db.select(models.Person)).scalar()
print('persons')
print(person.username)
if __name__ == '__main__':
start_server(host='0.0.0.0', port=5002, debug=True)
I am reading the documentation,
which explains that the function will
Create all tables stored in this metadata.
That leads me to believe Person is not associated with the db metadata.
You mentioned
when I put the class inside the start_server function it ... creates the table
Your from person import Person is nice enough,
but I suspect we wanted a simple import person.
In many apps the idiom would be import models.
Failing that, you may be able to point
create_all in the right direction
with this optional parameter:
tables – Optional list of Table objects, which is a subset of the total tables in the MetaData
Please let us know
what technical approach worked for you.
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.
The following error message is displayed even though it should have been done correctly.
I've included my code below, the error code and the
I have attached an image of the pip3 list.
from flask import Flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import pytz
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50), nullable=False)
body = db.Column(db.String(3000), nullable=False)
created_at = db.Column(db.DateTime, nullable=False,
default=datetime.now(pytz.timezone('Asia/Tokyo')))
#app.route('/')
def index():
return render_template('index.html')
#app.route('/create')
def create():
return render_template('create.html')
Error code.
from flask_sqlalchemy import SQLAlchemy ModuleNotFoundError was
raised, there is no module named 'flask_sqlalchemy'.
This happens to me often with VS Code, usually restarting VS Code it fixes it.
Im trying to connect my first Flask app with SQLAlchemy and PostGreSQL but got stuck with the following error.
UserWarning: Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. Defaulting SQLALCHEMY_DATABASE_URI to "sqlite:///:memory:".
'Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. '
After several hours of debugging for something that may be very simple I ran out of options. From the error seems like the issue is with the variables for SQLAlCHEMY_DATABASE_URI, but not 100% sure. I tried localhost and localhost:5000` but same error.
Reading other answers in SO, I saw that some times people get this issue when defining the config after the db = SQLAlchemy(app) but I don't have it like this in my code. Any leads are greatly appreciated.
from flask import Flask, request, render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.update(
SECRET_KEY='rafadbpw',
SQLAlCHEMY_DATABASE_URI='postgresql://postgres:rafadbpw#localhost:5000/catalog_db',
SQLALCHEMY_TRACK_MODIFICATIONS=False
)
db = SQLAlchemy(app)
#app.route('/index')
#app.route('/')
def hello_flask():
return "Hello Flask!"
class Publication(db.Model):
__tablename__ = 'publication'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
def __init__(self,id,name):
self.id = id
self.name = name
def __repr__(self):
return 'The id is {}, name is {}'.format(self.id, self.name)
if __name__ == '__main__':
db.create_all()
app.run(debug=True)
HELP, I have this appp.py file:
from flask import Flask, jsonify, request, make_response
import json
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
import models,resources
app = Flask(__name__)
api = Api(app)
api.add_resource(resources.UserRegistration, '/registration')
api.add_resource(resources.UserLogin, '/login')
api.add_resource(resources.UserLogoutAccess, '/logout/access')
api.add_resource(resources.UserLogoutRefresh, '/logout/refresh')
api.add_resource(resources.TokenRefresh, '/token/refresh')
api.add_resource(resources.AllUsers, '/users')
api.add_resource(resources.SecretResource, '/secret')
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'waaahawhawaahhawhaw'
db = SQLAlchemy(app)
#app.before_first_request
def create_tables():
db.create_all()
#app.route('/')
def index():
return jsonify({'message': 'Hell to the World!'})
if __name__ == '__main__':
app.run(debug = True)
and here are the models.py file:
from appp import db
class UserModel(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(120), unique = True, nullable = False)
password = db.Column(db.String(120), nullable = False)
def save_to_db(self):
db.session.add(self)
db.session.commit()
#classmethod
def find_by_username(cls, username):
return cls.query.filter_by(username = username).first()
and the resources.py file
from flask_restful import Resource, reqparse
from models import UserModel
parser = reqparse.RequestParser()
parser.add_argument('username', help = 'This field cannot be blank', required = True)
parser.add_argument('password', help = 'This field cannot be blank', required = True)
class UserRegistration(Resource):
def post(self):
data = parser.parse_args()
if UserModel.find_by_username(data['username']):
return {'message': 'User {} already exists'. format(data['username'])}
new_user = UserModel(
username = data['username'],
password = data['password']
)
try:
new_user.save_to_db()
return {
'message': 'User {} was created'.format( data['username'])
}
except:
return {'message': 'Something went wrong'}, 500
Once I try the run the app I get this error message:
ImportError: cannot import name 'UserModel'
Indeed I found other question like mine and they helped me understand why I'm getting this error but none of them helped me work around it.
My guess is that python (or flask) can't load the class UserModel from model.py because of model.py (or the class UserModel) is still initializing and it needs db from appp.py which is waiting for resources.py which cannot be loaded cuz it's waiting for models.py.
How to fix this ???? btw I'm new to all this and I'm just following this tutorial
Here is the project structure
test
|---appp.py
|---models.py
|---resources.py
The 3 files are next to each other in the test folder.
Thank you
To expand, here is an example in the the context of my comment..
from test.models import User, Role, UserRoles,\
Regions, RegionAttributes, CityAttributes,\
UserAttributes, SkillTracker, RegionWar,\
Articles
You requested that I explain the differences with importing.
I'm not sure it's something one can explain in a few words but ill try my best to not overcomplicate it.
You have your project folder called test and writhing this folder is your models.py. Because models file is within the test folder (test is a module in this case) you're importing a class, within a file, within a project directory, which ends up looking like this:
from test import models
--test
|
--models.py
In plain English you could say it means, from the test folder, I want to import the file models.py
Hope this adds some clarity, this would be a well googled search, I'm sure there are lots more better explanations out there and I'm probably missing something out.
The reason why one way didn't work, was because you have to import from a module, while app, models and UserModel are not modules.
You must create a separate file to write the db syntax, then import it in models
in db.py:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
on main of app.py you can put this code:
if __name__=='__main__':
from db import db
db.init_app(app)
app.run(port=5000)