I am a beginner writing a todo app in flask and in writing database application, at least I have never setup db for any production app myself.
I have written this code (models.py) that uses sqlalchemy ORM to define table model.
from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from datetime import datetime
from .extensions import db
from .config import app
# define base for declarative ORM
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = Column(String, unique=True)
password = Column(String)
def __repr__(self):
return '<User {}>'.format(self.username)
class Todo(Base):
__tablename__ = 'todos'
id = Column(db.Integer, primary_key=True)
title = Column(db.String(255))
description = Column(db.Text)
created_at = Column(db.DateTime, default=datetime.utcnow)
completed = Column(Boolean)
user_id = Column(db.Integer, db.ForeignKey('user.id'))
user = relationship('User', back_populates='todos')
def __repr__(self):
return '<Todo {}>'.format(self.id)
User.todos = relationship('Todo', order_by=Todo.id, back_populates='user')
# create database engine
engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
# create all tables
Base.metadata.create_all(engine)
extensions.py
from .config import app
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
config.py
from flask import Flask
from datetime import timedelta
app = Flask(__name__)
finally the start.py
from todo_app.extensions import db
from flask import Flask
from todo_app.endpoint import todo_bp, auth_bp
def create_app(config_file='settings.cfg'):
app = Flask(__name__, instance_relative_config=True)
app.config.from_pyfile(config_file)
db.init_app(app)
app.register_blueprint(auth_bp)
app.register_blueprint(todo_bp)
return app
if __name__ == '__main__':
app = create_app()
app.run()
but when I run the command python start.py
I get the following error:
$ python start.py
* Running on http://127.0.0.1:5000 (Press CTRL C to quit)
[2022-12-29 20:01:57,004] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "/home/ciasto/Dev/crud_app/crud_app_env/lib/python3.10/site-packages/flask/app.py", line 2077, in wsgi_app
response = self.full_dispatch_request()
File "/home/ciasto/Dev/crud_app/crud_app_env/lib/python3.10/site-packages/flask/app.py", line 1525, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/ciasto/Dev/crud_app/crud_app_env/lib/python3.10/site-packages/flask_restplus/api.py", line 584, in error_router
return original_handler(e)
File "/home/ciasto/Dev/crud_app/crud_app_env/lib/python3.10/site-packages/flask/app.py", line 1523, in full_dispatch_request
rv = self.dispatch_request()
File "/home/ciasto/Dev/crud_app/crud_app_env/lib/python3.10/site-packages/flask/app.py", line 1509, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/home/ciasto/Dev/crud_app/src/todo_app/endpoint.py", line 105, in index
user = User.query.filter_by(id=user_id).first()
AttributeError: type object 'User' has no attribute 'query'
This is the endpoint.py
# todo index endpoint
@todo_bp.route('/')
def index():
# get the logged in user
user_id = session.get('user_id')
user = User.query.filter_by(id=user_id).first()
# get the todo items for the user
todos = user.todos
return render_template('index.html', todos=todos)
CodePudding user response:
Your code is mixing idioms from the base SQLAlchemy package and Flask-SQLAlchemy. When using Flask-SQLAlchemy, your model classes should inherit from db.Model
, not Base
(db.Model
extends Base
further, and adds some Flask-SQLAlchemy features, like the query
attribute).
In fact, the majority of common SQLAlchemy features that you might want to use are exposed through the db
namespace in Flask-SQLAlchemy - you should rarely need to import SQLAlchemy itself.
See also this Q&A for the reverse of this problem.