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
Related
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
I have a flask app with SQLAlchemy trying to connect to sqlite app.db file.
When I run the app (python run.py) it says:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file
Relevant project structure:
/app
__init__.py
models.py
/db
app.db
run.py
config.py
My run.py file as follows:
from app import create_app
app = create_app()
app.run()
This imports and runs a create_app function from init.py file:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from .home.routes import home_bp
from .students.routes import students_bp
from .datasets.routes import datasets_bp
from .reports.routes import reports_bp
def create_app():
"""Create Flask application."""
app = Flask(__name__)
app.config.from_object('config')
# Initialise extensions
db = SQLAlchemy(app)
db.create_all()
with app.app_context():
# Import parts of our application
from .home import routes
from .students import routes
from .datasets import routes
from .reports import routes
# Register Blueprints
app.register_blueprint(home_bp)
app.register_blueprint(students_bp)
app.register_blueprint(datasets_bp)
app.register_blueprint(reports_bp)
return app
Database config is loaded from config.py:
from dotenv import load_dotenv
load_dotenv()
# DB Config
DB_FILE = 'db/app.db'
SQLALCHEMY_DATABASE_URI = 'sqlite:///db/app.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
The models.py file:
import db
class Student(db.Model):
id = db.Column(db.Integer, primary_key=True)
usi = db.Column(db.String(64), index=True)
first_name = db.Column(db.String(256))
last_name = db.Column(db.String(256))
dob = db.Column(db.String(64))
active = db.Column(db.Boolean)
def to_dict(self):
return {
'usi': self.usi,
'first_name': self.first_name,
'last_name': self.last_name,
'dob': self.dob,
'active': self.active
}
I have created a website using flask (python). I would like to create my SQLAlchemy database models in a separate file and import them. I have tried the following code but getting import error. I have tried solutions from similar questions but none is working. What modifications are needed to be made in my code?
structure
main.py
from Website import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
init.py (underscore not displayed)
from flask import Flask
from .routes import routes
from flask_sqlalchemy import SQLAlchemy
from .dbmodels import Subscribers
DB_NAME = "myDatabase.db"
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
#..........................Register blueprint.......................#
app.register_blueprint(routes, url_prefix='/')
#..........................Database config.......................#
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
db.create_all()
sub_1 = Subscribers(name="pavan")
db.session.add(sub_1)
db.session.commit()
return app
dbmodels.py
from . import db
from datetime import datetime
class Subscribers(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow())
def __repr__(self):
return '<User %r>' % self.name
You import Subscribers from dbModels in __init__ and db from __init__ in dbModelds. It leads to circular imports.
The simpliest solution - put db = SQLAlchemy() in separate file (e.g. extensions.py and import it from this file in __init__ and in dbModels
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
So Im trying to create a website using flask and SQLAlchemy for database storage but I keep getting the two aforementioned errors
Here is my app.py code
import os
from flask import Flask, session,render_template, request
from flask_session import Session
from sqlalchemy import create_engine,Column, Integer, String
from sqlalchemy.orm import scoped_session, sessionmaker
from flask_sqlalchemy import SQLAlchemy
from models import *
app = Flask(__name__)
#app.config["DATABASE_URL"] = "sqlite:////plz_work.db"
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("DATABASE_URL")
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)
# Check for environment variable
#if not os.getenv("DATABASE_URL"):
# raise RuntimeError("DATABASE_URL is not set")
# Configure session to use filesystem
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Set up database
engine = create_engine(os.getenv("DATABASE_URL"))
db = scoped_session(sessionmaker(bind=engine))
class User:
def __init__(self,username,password):
self.username = username
self.password = password
#app.route("/")
def index():
return render_template('index.html')
#app.route("/registration.html")
def registration():
return render_template('registration.html')
#app.route("/send", methods = ['GET','POST'])
def send():
username = request.form['username']
password = request.form['password']
users = User(username,password)
db.session.add(users)
db.session.commit()
return render_template('index.html')
if __name__ == "__main__":
app.run(debug = True)
db.create_all()
and here is my models.py file
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class USERS(db.Model):
__tablename__ = "Users"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String)
password = db.Column(db.String)
def __repr__(self):
value = "USER:({}, {})".format(self.username, self.password)
return value
I have been looking online for a soloution for so long but I can not find anything that works for me, and I have spent 2 days just on this problem, any help will be appreciated.
Thank You !!
I guess you're overriding your database object within your models.py file.
I suggest you to use sqlalchemy itself or flask-sqlalchemy not using them together. In my opinion things get complicated if you use them together.
You can achive that like this:
in your app.py
...your_other_imports...
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from .models import *
app = Flask(__name__)
...your_other_configs...
# Set up database
engine = create_engine(os.getenv("DATABASE_URL"))
db = scoped_session(sessionmaker(bind=engine))
#NOW db carries your database session
#Do not define your database models in app.py remove User class from here.
#You should define your database model and also your query method (not necessary)
#if you're used to query with flask-sqlalchemy. Would make queries look similar to you
dbModel = declarative_base()
dbModel.query = db.query_property()
# define the function which will create your tables
def init_db():
from .models import *
dbModel.metadata.create_all(bind=engine)
...your_routes...
if __name__ == "__main__":
app.run(debug = True)
# now call the function to create your tables
init_db()
in your models.py
from .app import dbModel
from sqlalchemy import Column, Integer, String
class User(dbModel):
__tablename__ = "users"
id = Columnn(Integer, primary_key=True)
username = Column(String)
password = Column(String)
def __repr__(self):
value = "USER:({}, {})".format(self.username, self.password)
return value
Using query_property you can now query your data from your database and use your session to put data in your database like this:
User.query.filter_by(username=...).first()
newUser = User(
username=...,
password=...
)
db.add(newUser)
db.commit()