I'm trying to create a table in an existing db with SQLAlchemy/SQLite where I have to store a user and password, but it returns an error saying the column pwd doesn't exist!
Am I missing something? Am I messing it up?
I still didn't quite understand, I followed all steps in some online tutorial but nothing still.
Here is the class object that I developed, then from another register form I try to store the pw from the application, but the error should be here in this code:
import os
basedir = os.path.abspath(os.path.dirname(__file__))
# flask imports
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from sqlalchemy import *
# create flask app
app = Flask(__name__)
# set sqllite db connection
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')
engine= create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
# bcrypt extension init to app
bcrypt = Bcrypt(app)
# sqlite init to app
db = SQLAlchemy(app)
# define meta data for table
meta=MetaData()
userstable = Table('users', meta, Column('id', Integer, primary_key = True, autoincrement=True), Column('username', String, unique=True), Column('pwd', String))
# create table to sqlite
meta.create_all(engine)
class User(db.Model):
# user columns
id = db.Column(db.Integer(), primary_key=True, autoincrement=True)
username = db.Column(db.String(64), unique=True)
pwd = db.Column(db.String(128))
def __init__(self,username,pwd):
#self.id=id
self.username=username
self.pwd=bcrypt.generate_password_hash(pwd)
# create user object
user = User('anish','23434')
# insert user object to sqlite
db.session.add(user)
# commit transaction
db.session.commit()
This is the error:
sqlalchemy.exc.OperationalError OperationalError: (sqlite3.OperationalError) table user has no column named pwd [SQL: INSERT INTO user (username, pwd) VALUES (?, ?)] [parameters: ('ita_itf', '$2b$12$VmpTsd0o4uTLj0wGypGu7ujhzYHLlV8k9ekaIP1.yh5lUMMgOM4MC')]
import os
basedir = os.path.abspath(os.path.dirname(__file__))
# flask imports
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from sqlalchemy import *
# create flask app
app = Flask(__name__)
# set sqllite db connection
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')
engine= create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
# bcrypt extension init to app
bcrypt = Bcrypt(app)
# sqlite init to app
db = SQLAlchemy(app)
# define meta data for table
meta=MetaData()
userstable = Table('users', meta, Column('id', Integer, primary_key = True, autoincrement=True), Column('username', String, unique=True), Column('pwd', String))
# create table to sqlite
meta.create_all(engine)
class User(db.Model):
# table name for User model
__tablename__ = "users"
# user columns
id = db.Column(db.Integer(), primary_key=True, autoincrement=True)
username = db.Column(db.String(64), unique=True)
pwd = db.Column(db.String(128))
def __init__(self,username,pwd):
#self.id=id
self.username=username
self.pwd=bcrypt.generate_password_hash(pwd)
# create user object
user = User('anish','23434')
# insert user object to sqlite
db.session.add(user)
# commit transaction
db.session.commit()
Related
I'm learning the way how to modularize flask application using blueprints and break database models into multiple files (one per entity)
I encounter a strange issue while building SQLite file and writing initial record for admin account, - SQLAlchemy added two records for one user.
Here is project layout and key files
runserver.py
#import os
from sbsuite import app
from sbsuite.database import init_db, createAdmin
init_db()
createAdmin()
if __name__ == "__main__":
app.run(debug=True)
models.py
from sbsuite import app
from sqlalchemy import Column, Integer, String
from sbsuite.database import Base
from flask_marshmallow import Marshmallow
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
email = Column(String(80))
password = Column(String(50))
roles = Column(String(50))
# JSON Schema
# should I create Marshmallow instance here?
ma = Marshmallow(app)
class UserSchema(ma.Schema):
class Meta:
fields = ('id', 'name', 'email', 'password')
user_schema = UserSchema()
users_schema = UserSchema(many=True)
database.py
from sbsuite import app
from sqlalchemy import create_engine
from sqlalchemy.orm import Session, scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from flask_sqlalchemy import SQLAlchemy
engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'], convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
from sbsuite.api.models import User, UserSchema
from sbsuite.api.productMdl import Product, ProductSchema
def init_db():
Base.metadata.create_all(bind=engine)
def createAdmin():
print("Create admin user")
admin = User(name="admin",email="admin#sbsuite.com", password="password", roles = "admin")
with Session(engine) as session:
session.add(admin)
session.commit()
print("admin user created") # why users added twice?
In last snippet after session.commit() I check database and see two records for admin user.
I created two databases using flask and sqlalchemy. My code is as follows:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from flask_login import UserMixin
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///C:\\Users\\dmac\\testmac.db'
app.config['SQLALCHEMY_BINDS'] = {
'User': 'sqlite:///C:\\Users\\dmac\\User.db',
'Stock': 'sqlite:///C:\\Users\\dmac\\Stock.db'
}
db = SQLAlchemy(app)
migrate = Migrate(app, db, render_as_batch = True)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
class Users(UserMixin, db.Model):
__table_name__ = 'users'
__bind_key__ = 'User'
__table_args__ = {'schema': 'User'}
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(100))
class Stock(db.Model):
__table_name__ = 'stock'
__bind_key__ = 'Stock'
__table_args__ = 'Stock'
id = db.Column(db.Integer, primary_key = True)
prices = db.Column(db.Float)
I tried to perform the flask-sqlalchemy upgrade after doing the migrate and init --multidb to fill my databases with table. However, I got the following error:
sqlalchemy.exc.OperationalError:(sqlite3.OperationalError) Unknown database "USER"[SQL:'\Create Table "User.users (id INTEGER not NULL, name VARCHAR(100))](Background on this error at: http://sqlalche.me/e/e3q8)
Any help would be appreciative. Thanks
I am trying to add the Product table into the database using flask sqlalchemy. It adds all the columns except for the userBudget
Does anyone know why?
On the cmd, I do
from app import db
db.create_all()
Then I go into sqlite3 and check the .schema but only the userBudget column is missing
sqlite> .schema
CREATE TABLE user (
id INTEGER NOT NULL,
username VARCHAR(15),
email VARCHAR(50),
password VARCHAR(80),
PRIMARY KEY (id),
UNIQUE (username),
UNIQUE (email)
);
CREATE TABLE product (
"userId" INTEGER NOT NULL,
"productURL" VARCHAR NOT NULL,
"currentPrice" INTEGER,
PRIMARY KEY ("userId"),
FOREIGN KEY("userId") REFERENCES user (id)
);
import requests
from flask import Flask, render_template, redirect, url_for, request
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
# Instantiation
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db' # location of database
SQLALCHEMY_TRACK_MODIFICATIONS = False # no sqlalchemy warnings in console
bootstrap = Bootstrap(app) # allows use of flask-bootstrap
db = SQLAlchemy(app) # database
# Initialization
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
# Database Tables
class User(UserMixin, db.Model): # UserMixin provides default implementations for the methods flask-login expects users to have
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(15), unique=True)
email = db.Column(db.String(50), unique=True)
password = db.Column(db.String(80))
class Product(db.Model):
userId = db.Column(db.Integer, db.ForeignKey(User.id), primary_key=True)
productURL = db.Column(db.String(), nullable=False)
currentPrice = db.Column(db.Integer)
userBudget = db.Column(db.Integer, nullable=False)
#login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
if __name__ == '__main__':
app.run(debug=True)
If you are still in development, do a db.drop_all() followed by a db.create_all().
You should track your db changes with e.g. https://github.com/miguelgrinberg/Flask-Migrate
There's something wrong with my model? do you se any anomaly? Trying to store a user and password to SQLite db with SQLAlchemy but returns an error saying the column pwd in the user table doesn't exist, indeed if I check sqlite> .schema it returns the table with the correct structure and pwd column, no data inside if I query though.
I firstly create the table with Table() function, then under I define the User class, maybe is because in the class there are no references to the column names of the table? but I have imported tablename="user" so it should work no?
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from sqlalchemy import *
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data-users.sqlite'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer(), primary_key = True, autoincrement=True)
username = db.Column(db.String(64), unique = True)
pwd = db.Column(db.String())
def __repr__(self):
return '<User %r>' % self.username
Here I store the user data in the table
from store_user_db import User, db
db.create_all()
DICP_FTP_DESTINATION_PSW=self.submit_pwd()
user = User(id=001,username="ita_itf",pwd=DICP_FTP_DESTINATION_PSW)
db.session.add(user)
db.session.commit()
This is the error:
sqlalchemy.exc.OperationalError
OperationalError: (sqlite3.OperationalError) table user has no column named pwd
[SQL: INSERT INTO user (id, username, pwd) VALUES (?, ?, ?)]
[parameters: (1, 'ita_itf', <read-only buffer for 0x7efe495709f0, size -1, offset 0 at 0x7efe500c3830>)]
The db.create_all() will only create tables if they don't already exist. I suspect that your issue is that you created the table in the recent past, at a point where you didn't yet have the pwd column in your model.
So now you run db.create_all() and it essentially does nothing (as the user table already exists) but falls over when you try to access the never created pwd column.
You can db.drop_all() to destroy all the current tables, or you could manually (or using a migration tool) add the 'missing' pwd column so the database matches the model.
Also, all this code doesn't do anything in this particular example (unless you're doing something unusual in code you haven't included).
engine= create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
#CREATE TABLE
meta=MetaData()
userstable = Table('user', meta, \
Column('id', Integer, primary_key = True, autoincrement=True), \
Column('username', String, unique = True), \
Column('pwd', LargeBinary,unique = True))
meta.create_all(engine)
Example Working Version
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///example.sqlite3"
bcrypt = Bcrypt(app)
db = SQLAlchemy(app)
class User(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer(), primary_key=True, autoincrement=True)
username = db.Column(db.String(64), unique=True)
pwd = db.Column(db.LargeBinary(), unique=True)
def __init__(self, id, username, pwd):
self.id = id
self.username = username
self.pwd = bcrypt.generate_password_hash(pwd)
if __name__ == "__main__":
db.drop_all() # destroy all the tables.
db.create_all() # create all fresh new tables.
u = User(1, "static", "password")
db.session.add(u)
db.session.commit()
u = User.query.first() # check out data got stored.
print(u.pwd)
Basically I'm trying to make a Flask app using flask-sqlalchemy. I want to first load up a bunch of data into my database (database.py). However, I can't get this to work or even create the myapp.db file.
I'm getting no errors, however myapp.db file is not being created.
>>> db.engine
Engine(sqlite://)
The above should be myapp something, I'm pretty sure.
I have simplified my code to make it more concise to the problem.
Here I have my app:
from flask import Flask
import os
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db_path = os.path.join(os.path.dirname(__file__), 'myapp.db')
db_uri = 'sqlite:///{}'.format(db_path)
SQLALCHEMY_DATABASE_URI = db_uri
db = SQLAlchemy(app)
from views import *
if __name__ == '__main__':
app.secret_key = os.urandom(12)
app.run(debug=True)
And I want to run my database.py to load all my data - which in my mind should be creating a myapp.db file??:
from flask_sqlalchemy import SQLAlchemy
import os
import re
from myapp import app
from models import *
## Creates our database
db.create_all()
username = test
password = test
user = User(username=username, password=password)
db.session.add(user)
db.session.commit()
Here is my models.py
from flask_sqlalchemy import SQLAlchemy
from myapp import app
# create a new SQLAlchemy object
db = SQLAlchemy(app)
class User(db.Model):
""""""
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, nullable=False)
password = db.Column(db.String, nullable=False)
Changing
SQLALCHEMY_DATABASE_URI = db_uri
to
app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
fixed it.