SQLAlchemy not creating table in database - python

I am creating a website using a flask with a signup form that saves the signup info in a database. however, it is not creating any tables in the database.
my init.py file looks like this:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
#intitialising databas: works correctly
db = SQLAlchemy()
DB_NAME = 'database.db'
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = 'shhh dont tell'
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
#importing our blue prints
from .views import views
from .auth import auth
app.register_blueprint(views,urlprefix='/')
app.register_blueprint(auth,urlprefix='/')
from .models import User
create_database(app)
return app
#database creates successfully
def create_database(app):
if not path.exists('website/source' + DB_NAME):
db.create_all(app=app)
print('Created Database')
and my models.py looks like:
from enum import unique
from sqlalchemy import true
from website.source import db
from flask_login import UserMixin
#schema of table according to mega tut and sqlalchemy
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
firstName = db.Column(db.String(150))
lastName = db.Column(db.String(150))
userName = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
I am not sure why this is happing. when I run the app on the flask and do my sign up form and click the submit button I get the error
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) table user has no column named userName
I have looked at multiple youtube tutorials and I seem to be doing everything correctly. any help would be appreciated
thanks

Related

Flask sqlalchemy, delete user returns Object is already attached to session '9' (this is '10')

I am trying to add delete user function to admin dashboard, now if i try to delete any user i get this error:
sqlalchemy.exc.InvalidRequestError: Object '<User at 0x29859f359a0>' is already attached to session '9' (this is '10')
models.py:
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
db = SQLAlchemy()
class User(UserMixin, db.Model):
"""User Model"""
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(25), unique=True, nullable=False)
password = db.Column(db.String(8), nullable=False)
role = db.Column(db.String(25), nullable=False)
main.py:
import time
import os
import random
from cryptography.fernet import Fernet
from flask import Flask, render_template, url_for, session, redirect, flash
from flask_socketio import SocketIO, send, leave_room, join_room
from wtf_forms import *
from models import *
from passlib.hash import pbkdf2_sha256
from flask_login import LoginManager, login_user, current_user, login_required, logout_user
# DATA BASE
app.config['SQLALCHEMY_DATABASE_URI'] = 'link'
db = SQLAlchemy(app)
# Configure flask login
login = LoginManager(app)
login.init_app(app)
#socketio.on('delete_user')
def on_delete(data):
""" delete user or admin"""
if data:
username, role = data['user'].split('_')
user = User.query.filter_by(username=username).first()
if user:
db.session.delete(user)
db.session.commit()
print('user deleted')
else:
print('user not deleted')
now how can i delete users from db successfully, and avoid getting this erro in the future.

sqlalchemy does not initialize the database

I have created a models.py file describing my schema. I am using the code below to create the DB and initialize it with the model.py schema. When I call the create_app function a new sqlite file gets create but it is empty. It is not picking up the schema from my models.py file.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy_utils.functions import database_exists
db = SQLAlchemy()
DB_NAME = "database.db"
def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
if not database_exists(app.config['SQLALCHEMY_DATABASE_URI']):
db.init_app(app)
db.create_all(app=app)
print(f'Created Database Successfully!!')
return app
models.py
from .main import db
from flask_login import UserMixin
from sqlalchemy.sql import func
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))
happened to me with missing init.py file in the package, maybe thats the case
After I imported the models file first, the DB was created sucessfully.

Flask application factory pattern init empty database, not my model on ubuntu

I want to create a flask application using the application factory pattern, I want to separate my logic and my models. The server starts without errors, but after I migrate my database it creates an empty db.
I'm currently using ubuntu, in windows it creates the db properly.
__init__.py:
from flask import Flask, request, jsonify
from .extensions import db
from flask_migrate import Migrate
migrate = Migrate()
def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
from .models import File
db.init_app(app)
migrate.init_app(app, db)
return app
The models.py:
from .extensions import db
class File(db.Model):
id = db.Column(db.Integer, primary_key=True)
audio_path = db.Column(db.String(255), unique=True)
original_txt = db.Column(db.String(255), unique=True)
corrected_txt = db.Column(db.String(255), unique=True)
creation_date = db.Column(db.DateTime)
def __repr__(self):
return 'File %r' % self.audio_path
extensions.py is where I define my SQLAlchemy db:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
Why is it not creating the database from my model?
this just works for me:
you need to declare db = SQLAlchemy() inside the models.py file, not in the extensions file, and then in the init.py file import db from models, init the db class by: db.init_app(app). and migrate.init_app(app, db).

Missing userloader or request_loader error

i have an isssue with flask-login the user loader is not working
Exception: Missing user_loader or request_loader. Refer to http://flask-login.readthedocs.io/#how-it-works for more info.
and
when i try to import the user model in shell:
AttributeError: 'LoginManager' object has no attribute 'load_user'
This is my code:
-------------------app/__init__.py----------------
from app.config import Config
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
#create app
app = Flask(__name__)
app.config.from_object(Config)
#init pckages
db = SQLAlchemy(app)
login_manager = LoginManager(app)
#import Blueprints
from app.blueprints.user.routes import user
from app.blueprints.dashboard.routes import dashboard
#register Blueprints
app.register_blueprint(user)
app.register_blueprint(dashboard)
------------------------------app.py-------------------------------
from app import app
if __name__ == "__main__":
app.run(debug=True)
------------------------------user model------------------------------------
from app import db, login_manager
from flask_login import UserMixin
#login_manager.load_user
def load_user(user):
return User.get(user)
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(20), unique=True, nullable=False)
avatar = db.Column(db.String(50), default="default.jpg")
password = db.Column(db.String(60), nullable=False)
def __repr__(self):
return self.username
The decorator should be
#login_manager.user_loader not load_user
Instead of :
#login_manager.load_user
def load_user(user):
return User.get(user)
try :
#login_manager.user_loader
def load_user(user):
return User.query.get(int(user))
You can make a slight modification to your current user model. As it is currently, you have:
#login_manager.load_user
def load_user(user):
return User.get(user)
Consider this:
Import LoginManager from flask_login
from flask_login import LoginManager
login = LoginManager(app)
Update your user model as follows:
from flask_login import UserMixin
from app import login # the variable from Flask-login
#login.user_loader
def load_user(id):
return User.query.get(int(id)) # slightly modified such that the user is loaded based on the id in the db
The user loader is registered with Flask-Login with the #login.user_loader decorator. The id that Flask-Login passes to the function as an argument is going to be a string, so databases that use numeric IDs need to convert the string to integer as you see above.

Error "NameError: name 'UsersAdmin' is not defined" when moved all classes to another file

Short story. I took this example:https://github.com/MrJoes/Flask-Admin/tree/master/examples/sqla i played with it and everything was fine until i decided what i want to split app.py(main file) to two parts. In main file app.py i will keep views and in another models.py i will keep all classes. Both files are in same folder.
Issue. I get error Error when running my app.py file:
"NameError: name 'UserAdmin' is not defined"
This is part from app.py file where i try to call Class UserAdmin from models.py file:
import os
import os.path as op
from flask import Flask, render_template, request, redirect, url_for, abort, session, flash
from flask_sqlalchemy import SQLAlchemy, Model
from flask_login import UserMixin, session, LoginManager, login_user, login_required, logout_user
from flask_bcrypt import Bcrypt,check_password_hash,generate_password_hash
from models import *
from flask_admin import Admin, BaseView, expose
app = Flask(__name__)
app.config['SECRET_KEY'] = '123456790'
app.config['DATABASE_FILE'] = 'db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
admin = Admin(app, name='Admin Site', template_mode='bootstrap3')
# Add views. This is where it fails
admin.add_view(UserAdmin(User, db.session))
models.py file where is described UserAdmin part:
from wtforms import validators
from app import db, app, url_for, admin
from flask_admin.contrib import sqla
from flask_admin.contrib.sqla import filters, ModelView
from flask_login import UserMixin
...
# Create models
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(100))
last_name = db.Column(db.String(100))
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
# Required for administrative interface. For python 3 please use __str__ instead.
def __str__(self):
return self.username
class UserInfo(db.Model):
id = db.Column(db.Integer, primary_key=True)
key = db.Column(db.String(64), nullable=False)
value = db.Column(db.String(64))
user_id = db.Column(db.Integer(), db.ForeignKey(User.id))
user = db.relationship(User, backref='info')
def __str__(self):
return '%s - %s' % (self.key, self.value)
class UserAdmin(sqla.ModelView):
inline_models = (UserInfo,)
...
If someone could point me what i am doing wrong there it would be very nice.
Thanks

Categories