I am working on a project for one of my courses at college. The project is a web application using flask and python to create the web application. I am having an issue with my project and the error I am returned is AttributeError: 'Blueprint' object has no attribute 'query' which refers to this line in my code "pagination = transaction.query.paginate(page, per_page, error_out=False)".
transaction init file
import csv
import logging
import os
from flask import Blueprint, render_template, abort, url_for,current_app
from flask_login import current_user, login_required
from jinja2 import TemplateNotFound
from app.db import db
from app.db.models import transaction
from app.transactions.forms import csv_upload
from werkzeug.utils import secure_filename, redirect
transaction = Blueprint('transaction', __name__,
template_folder='templates')
#transaction.route('/transactions', methods=['GET'], defaults={"page": 1})
#transaction.route('/transactions/<int:page>', methods=['GET'])
def transaction_browse(page):
page = page
per_page = 1000
pagination = transaction.query.paginate(page, per_page, error_out=False)
data = pagination.items
try:
return render_template('browse_transactions.html',data=data,pagination=pagination)
except TemplateNotFound:
abort(404)
app init file
"""A simple flask web app"""
import os
import flask_login
from flask import Flask
from flask_bootstrap import Bootstrap5
from flask_wtf.csrf import CSRFProtect
from flask_cors import CORS
from flask_mail import Mail
from app.auth import auth
from app.simple_pages import simple_pages
from app.cli import create_database
from app.db import database
from app.db import db
from app.db.models import User
from app.error_handlers import error_handlers
from app.logging_config import log_con, LOGGING_CONFIG
from app.context_processors import utility_text_processors
from app.transactions import transaction
mail = Mail()
login_manager = flask_login.LoginManager()
def create_app():
"""Create and configure an instance of the Flask application."""
app = Flask(__name__)
if os.environ.get("FLASK_ENV") == "production":
app.config.from_object("app.config.ProductionConfig")
elif os.environ.get("FLASK_ENV") == "development":
app.config.from_object("app.config.DevelopmentConfig")
elif os.environ.get("FLASK_ENV") == "testing":
app.config.from_object("app.config.TestingConfig")
app.mail = Mail(app)
login_manager.init_app(app)
login_manager.login_view = "auth.login"
csrf = CSRFProtect(app)
bootstrap = Bootstrap5(app)
app.register_blueprint(simple_pages)
app.register_blueprint(auth)
app.register_blueprint(database)
app.register_blueprint(log_con)
app.register_blueprint(error_handlers)
app.register_blueprint(transaction)
app.context_processor(utility_text_processors)
app.cli.add_command(create_database)
db.init_app(app)
api_v1_cors_config = {
"methods": ["OPTIONS", "GET", "POST"],
}
CORS(app, resources={"/api/*": api_v1_cors_config})
return app
#login_manager.user_loader
def user_loader(user_id):
try:
return User.query.get(int(user_id))
except:
return None
database models init file
from datetime import datetime
from sqlalchemy import Integer, ForeignKey
from sqlalchemy.orm import relationship, declarative_base
from werkzeug.security import check_password_hash, generate_password_hash
from app.db import db
from flask_login import UserMixin
from sqlalchemy_serializer import SerializerMixin
Base = declarative_base()
transaction_user = db.Table('transaction_user', db.Model.metadata,
db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
db.Column('transaction_id', db.Integer, db.ForeignKey('transaction.id'))
)
class transaction(db.Model,SerializerMixin):
__tablename__ = 'transaction'
id = db.Column(db.Integer, primary_key=True)
type = db.Column(db.String(10), nullable=True, unique=False)
amount = db.Column(db.Integer)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
user = relationship("User", back_populates="transaction", uselist=False)
def __init__(self, type, amount):
self.type = type
self.amount = amount
Related
So im still learning about the structure in flask it seems flask give a too much flexibilty which is kinda confusing for me to decide, so im trying to add my Resource class to the API with the current structure
api
/__init__.py
/project.py
models
/project_management.py
configs.py
configs.json
run.py
but it return error when running
AttributeError: type object 'Project' has no attribute 'as_view'
Traceback (most recent call last):
File "e:\project-py\run.py", line 6, in
from api import * File "e:\project-py\api_init_.py", line 9, in
from .project import * File "e:\project-py\api\project.py", line 6, in
#api.add_resource(Project, '/v1/project') File "C:\Users\rokie\Anaconda3\envs\py39-rest-flask\lib\site-packages\flask_restful_init_.py",
line 391, in add_resource
self.register_view(self.app, resource, *urls, **kwargs) File "C:\Users\rokie\Anaconda3\envs\py39-rest-flask\lib\site-packages\flask_restful_init.py",
line 431, in _register_view
resource_func = self.output(resource.as_view(endpoint, *resource_class_args, AttributeError: type object 'Project' has no attribute 'as_view'
My run.py
from functools import wraps
from flask import Flask, session, g, render_template, flash
# from flask_cors import CORS, cross_origin
from flask_wtf.csrf import CSRFProtect
from pages import *
from api import *
from config import create_app
app = create_app()
app.app_context().push()
# app.register_blueprint(pages)
app.register_blueprint(api, url_prefix='/api')
# app.secret_key = "ff82b98ef8727e388ea8bff063"
csrf = CSRFProtect()
csrf.init_app(app)
if __name__ == "__main__":
app.run(host='127.0.0.1',debug=True)
Config.py
import json
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
# from flask_wtf.csrf import CSRFProtect
from flask_login import LoginManager
from flask_cors import CORS, cross_origin
db = SQLAlchemy()
ma = Marshmallow()
f = open('configs.json')
config = json.load(f)
def create_app():
app = Flask(__name__, template_folder='templates')
app.config['SQLALCHEMY_DATABASE_URI'] = config['config']['database']
app.config['SECRET_KEY'] = config['config']['secret_key']
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
api_v1_cors_config = {
"origins": ["*"]
}
CORS(app, resources={
r"/api/*": api_v1_cors_config
})
db.init_app(app)
ma.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'pages.login'
login_manager.init_app(app)
from models.user_management 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))
return app
api init.py folder with the name 'api' as the package
from flask import Blueprint
from flask_restful import Api
api_bp=Blueprint('api',__name__)
api = Api(api_bp)
# from .login import *
# from .api_project import *
from .project import *
# from .master_user import *
and lastly the project.py
from . import api
from flask import Flask, jsonify, request
from flask_restful import Resource, Api
from models.project_management import Project, ProjectStatus, Task
#api.add_resource(Project, '/v1/project')
class Project(Resource):
def get(self):
try:
print('test')
projects = Project.query.all()
return jsonify({
'message': 'Data get success',
'data': projects,
})
except Exception as e:
return jsonify({
'message': f'failed to get data {e}',
'data': []
})
enter code here
I can't check it but ...
You have the same name Project for model (Project.query.all()) and for class class Project(Resource) and this can make problem.
Because model Project is created (imported) before add_resource() so it uses this model but it has to use class Project
You may have to first define class with different name and later use add_resource() using new class
class MyProject(Resource):
# ... code ...
api.add_resource(MyProject, '/v1/project')
I've been building a Flask app with the help of this video:
https://www.youtube.com/watch?v=dam0GPOAvVI&t=3256s
Here is the file of my init so far :
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
DB_NAME = "database.db"
db = SQLAlchemy()
app = Flask(__name__)
app.config['SECRET_KEY'] = 'bindthemostselling'
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
from views import views
from auth import auth
app.register_blueprint(views, url_prefix='/')
app.register_blueprint(auth, url_prefix='/')
if __name__ == '__main__':
app.run(debug=True)
and here is the file of my models so far its just one class:
from flask_login import UserMixin
from . import db
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
first_name = db.Column(db.String(150))
My problem is that the db.Column inside the User class is unrecognizable. I've tried to reinstall sqlalchemy and flask and i've looked at everything he did again and even copied the code from his github and it still wont recognize that function or even other functions that I have noticed so far from the video. This is the first time I try to make an actual python app so maybe there is something i'm missing in the syntax?
Thanks in advance.
EDIT:
So i have updated the init file to include everything so i can run and see what error i get here is what I have now:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
from models import User
from flask_login import LoginManager
DB_NAME = "database.db"
db = SQLAlchemy()
app = Flask(__name__)
app.config['SECRET_KEY'] = 'bindthemostselling'
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
from views import views
from auth import auth
app.register_blueprint(views, url_prefix='/')
app.register_blueprint(auth, url_prefix='/')
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
def create_database(app):
if not path.exists('.' + DB_NAME):
db.create_all(app=app)
print('Created Database!')
create_database(app)
if __name__ == '__main__':
app.run(debug=True)
Here is the traceback that I got (Sorry if the formatting is bad):
Traceback (most recent call last):
File "c:\Users\Ashraf\FlaskToDo_init_.py", line 4, in
from models import User
File "c:\Users\Ashraf\FlaskToDo\models.py", line 2, in
from . import db
ImportError: attempted relative import with no known parent package
so apparently the db is not imported correctly? This can't be true cause when I created the User class and passed the db.Model, it recognized it. What am I exactly missing here?
Try changing the import statement in the models file from
from . import db
to:
from init import db
This way you should get a circular import error, so move from models import User in your init after db is defined.
This is the complete setup:
init:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
from flask_login import LoginManager
DB_NAME = "database.db"
db = SQLAlchemy()
app = Flask(__name__)
app.config['SECRET_KEY'] = 'bindthemostselling'
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
def create_database(app):
if not path.exists('.' + DB_NAME):
db.create_all(app=app)
print('Created Database!')
create_database(app)
if __name__ == '__main__':
app.run(debug=True)
from models import User
models:
from flask_login import UserMixin
from init import db
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
first_name = db.Column(db.String(150))
EDIT:
add a route to actually navigate in your app:
#app.route("/")
def home():
return "Hello World"
I spent all afternoon trying to figure this out. I've checked the flask documentation, mostly flask-marshmallow documentation most notably the sqlalchemy integration part and some other stackoverflow questions.
Is this something to do with serialization? I thought it was taken care of by using the flask-sqlalchemy package?
When I run this with a postman request, I get:
{
"name": [
"Unknown field."
]
}
My code:
Schema
from ma import ma
from models.form import FormModel
class FormSchema(ma.SQLAlchemySchema):
class Meta:
model = FormModel
Model
from db import db
class FormModel(db.Model):
__tablename__ = "forms"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
Resource
from flask_restful import Resource
from flask import request
from models.form import FormModel
from schemas.form import FormSchema
from db import db
form_schema = FormSchema()
class NewForm(Resource):
#classmethod
def post(cls):
print("Request:")
print(request.get_json())
print("Form schema load:")
#print(form_schema.load(request.get_json()))
form = form_schema.load(request.get_json())
print("Form")
#print(form)
db.session.add(form)
db.session.commit()
#form_schema.dump(form)
app.py
from flask import Flask, jsonify
from flask_restful import Api
from marshmallow import ValidationError
from db import db
from ma import ma
from models.form import FormModel
from schemas.form import FormSchema
from resources.form import NewForm
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///test.db"
api = Api(app)
#app.before_first_request
def create_tables():
db.create_all()
#app.errorhandler(ValidationError)
def handle_marshmallow_validation(err):
return jsonify(err.messages), 400
api.add_resource(NewForm, "/form")
if __name__ == "__main__":
db.init_app(app)
ma.init_app(app)
app.run(port=5000, debug=True)
db.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
ma.py
from flask_marshmallow import Marshmallow
ma = Marshmallow()
Figured it out!
The schema isn't correct. It should be:
class FormSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = FormModel
load_instance = True
I changed ma.SQLAlchemySchema to ma.SQLAlchemyAutoSchema
And added load_instance = True
I am trying to separate my code into files. When I am trying to import any variables from another file I get the following error:
File ".\app.py", line 2, in <module>
from backend.Measure import Measure,MeasurementSchema,measure_schema,measures_schema
ModuleNotFoundError: No module named 'backend'
I have 3 files:
app.py
from flask import Flask, Request, jsonify
from backend.Measure import Measure,MeasurementSchema,measure_schema,measures_schema
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
#app.route('/api/measures')
def getAllMeasurements():
results = Measure.query.all()
return measures_schema.jsonify(results)
Measure.py
from flask_marshmallow import Marshmallow
from backend.app import app
from backend.app import db
ma = Marshmallow(app)
class Measure(db.Model):
__tablename__ = 'measurements'
id = db.Column(db.Integer, primary_key=True)
timestamp = db.Column(db.DateTime, auto_now_add=True)
temperature = db.Column(db.Float)
def __init__(self, timestamp, temperature):
self.timestamp = timestamp
self.temperature = temperature
class MeasurementSchema(ma.Schema):
class Meta:
fields = ('id', 'timestamp', 'temperature')
measure_schema = MeasurementSchema()
measures_schema = MeasurementSchema(many=True)
db.py
from sqlalchemy import create_engine
server = 'localhost'
database = 'TESTDB'
driver = 'SQL Server Native Client 11.0'
connection_string = f'mssql+pyodbc://#{server}/{database}?trusted_connection=yes&driver={driver}'
app.config['SQLALCHEMY_DATABASE_URI'] = connection_string
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
engine = create_engine(connection_string)
connection = engine.connect()
All files are in the backend folder as shown in the image below
What am I missing?
If you want to import a file from the same folder, you should do this.
In Measure.py
from .app import app
from .app import db
In app.py
from .Measure import Measure,MeasurementSchema,measure_schema,measures_schema
I have flask project which work on presently. (below)
When I run this project using command
python run.py
I get following error.
Traceback (most recent call last):
File "run.py", line 1, in
from site import app
ImportError: cannot import name 'app'
run.py
from site import app
import os
app.secret_key = os.urandom(24)
port = int(os.environ.get('PORT', 5000))
if __name__ == '__main__':
app.run(debug="True")
# app.run(host='0.0.0.0', port=port)
__init__.py
from .views import app
from .models import db
db.create_all()
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:password#localhost:5432/db'
app.config['SECURITY_REGISTERABLE'] = True
views.py
from flask import Flask
from .models import User, db
from flask import render_template, request, redirect, url_for
from flask.ext.security import login_required
app = Flask(__name__, static_url_path='')
#app.route('/')
def index():
return render_template('index.html')
#app.route('/profile/<email>')
#login_required
def user_index(email):
user = User.query.filter_by(email=email).first()
return render_template('profile.html', user=user)
#app.route('/post_user', methods=['POST'])
def post_user():
if request.form["action"] == "submit_btn":
user = User(request.form['username'], request.form['email'])
db.session.add(user)
db.session.commit()
return redirect(url_for('index'))
models.py
from flask import Flask
from flask.ext.mail import Mail, Message
from flask_sqlalchemy import SQLAlchemy
from flask.ext.security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin
app = Flask(__name__, static_url_path='')
db = SQLAlchemy(app)
mail = Mail()
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), unique=True)
password = db.Column(db.String(255))
active = db.Column(db.Boolean())
confirmed_at = db.Column(db.DateTime())
roles = db.relationship('Role', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'))
What should be the directory structure? Also how should I import the models and views in order to make the server work?
Please tell me if you need any other info, thanks in advance.
Rename the site's name so python dont try to import the site standard library, also is better to define the app inside the init.py file: Docs