Flask SQLAlchemy - Unable to open database file - python

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
}

Related

When I inherit sqlalchemy (flask app) in a class, it doesn't recognize functions such as Column()

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"

Mapping sql alchemy database models defined in a separate file

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

No module named 'backend'

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

flask_sqlalchemy create model from different file

I am trying to define and create my models with flask_sqlalchemy.
If I do it all in one script, it works:
all_in_one.py
from config import DevConfig
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_object(DevConfig)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = app.config.get("DB_URI")
db = SQLAlchemy(app)
class Members(db.Model):
id = db.Column(db.String, primary_key=True, nullable=False)
def main():
db.drop_all()
db.create_all()
if __name__ == "__main__":
main()
The Members table is created.
If I split this process into files, I can't seem to get the db object to register my Members model and do anything.
root
│-- config.py
│-- create.py
│-- database.py
│-- members.py
database.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
members.py
from database import db
class Members(db.Model):
id = db.Column(db.String, primary_key=True, nullable=False)
create.py
from database import db
from config import DevConfig
from flask import Flask
app = Flask(__name__)
app.config.from_object(DevConfig)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = app.config.get("DB_URI")
def main():
db.init_app(app)
with app.app_context():
db.drop_all()
db.create_all()
if __name__ == "__main__":
main()
The Members table does not get created.
add import members below db.init_app(app)
from database import db
from config import DevConfig
from flask import Flask
app = Flask(__name__)
app.config.from_object(DevConfig)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = app.config.get("DB_URI")
def main():
db.init_app(app)
import members
with app.app_context():
db.drop_all()
db.create_all()
if __name__ == "__main__":
main()

Flask directory Structure

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

Categories

Resources