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)
Related
Before you answer:
I am using flask-sqlalchemy library for Python app.py webapp, and a SQLite database referred as sqlite:///mydb.db
from flask import Flask, render_template, request, redirect
from flask_sqlachemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI] = 'sqlite:///mydb.db'
db = SQLAlchemy (app)
class Mydb(db.Model):
id = db.Column(db.Integer, primary_key = True)
userName = db.Column(db.String(30), nullable = False, unique = True)
pwd = db.Column(db.String(30), nullable = False)
created = db.Column(db.DateTime, default=datetime.utcnow)
...... AND IT GOES ON FURTHER
I've created a database, and it is getting entries from a HTML form. The database is working fine and it has few entries.
Question
How can I grab ID(/IDs) of a particular entry inside database if I know that(/those) entry(entries) exists(/exist) in our database? ID is defined as
db.Column(db.Integer, primary_key = True)
It would be great if no new library is used for it.
I know
bool(Model.query.filter_by(user='John').first())
will tell me if user with the name of 'John' exists but how can I get ID(/IDs) of this entry after knowing that it exists?
Model.query.filter_by(user='John').first() returns the object in the database:
user = Model.query.filter_by(user='John').first()
if user:
id = user.id
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()
I'm trying to store a user and password in a table I created with sqlite db. It seems that pwd column doesn't exist, while if I check the table in sqlite it does contain the column.
The error returns the following:
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', '$2b$12$j5NPKCgv8DsFnOJtHE2xjOyXMoGSFCz89Gf/Oy2Hs.FfEx/0BuOY2')]
(Background on this error at: http://sqlalche.me/e/e3q8)
ERROR DETAILS:
File "/home/itad/DICP_evo_dev/venv/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 552, in do_execute
def do_executemany(self, cursor, statement, parameters, context=None):
cursor.executemany(statement, parameters)
def do_execute(self, cursor, statement, parameters, context=None):
cursor.execute(statement, parameters)
def do_execute_no_params(self, cursor, statement, context=None):
cursor.execute(statement)
def is_disconnect(self, e, connection, cursor):
this is the User class I created:
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data-users.sqlite'
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.String(128))
def __init__(self,id,username,pwd):
self.id=id
self.username = username
self.pwd = bcrypt.generate_password_hash(pwd)
This is the code where I manually insert the password with a python GUI in my app:
from store_user_db import User, db
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()
Here I check the user table if exist and the schema, I also tried to run sqlite>SELECT * FROM user but it doesn't return any result
itad#itad-virtual-machine:~/DICP_evo_dev$ sqlite3 data-users.sqlite
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
sqlite> .schema user
CREATE TABLE user (
id INTEGER NOT NULL,
username VARCHAR,
pwd VARCHAR,
PRIMARY KEY (id),
UNIQUE (username)
);
Maybe it's easier if I show you the screenshots, the commented part is the one I used to create the table, then I commented it because you only need to create it once.
PYTHON CODE
SQLITE FROM COMMAND PROMPT
I didn't put that in the code but I previously did create the db and the table with the function table() then create_all() etc.. Then I comment that out. indeed if I type sqlite> .schema user, it shows the table, should be there in the db no?
i think issue is with the declaration of user variable 2 times in models
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.String(128))
def __init__(self,id,username,pwd):
db.Model.__init__(self, id=id, username=username, pwd=pwd)
this will solve the problem.
Seems like your table is not being created, try running 'python' (to run REPL), import the class that has the db object and run 'db.create_all()' (This will create tables in DB according to your models)
Looking at the code where I create the table and then I create the User class, there might be some issue because in the User class I'm using User(db.Model) while when I create the table just before I'm using engine and Metadata() function? Indeed when I create the table there's no reference to db.
Screenshot below, code on the left:
https://i.stack.imgur.com/LMwhO.jpg
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
I am following this tutorial https://www.youtube.com/watch?v=kuyrL6krkwA. I have modified the db, table, and columns names for my app. Everything else is identical to tutorial. The error occurs (10 mins into tutorial) where he enters python shell and runs the following commands:
from models import User # my app uses 'User' not 'BlogPost'
users = User.query.all()
The Python Shell Script returns error message below:
sqlalchemy.exc.OperationalError: (OperationalError) no such
column:users.id u'SELECT users.id AS users_id, users.name AS
users_name, users.zipcode AS users_zipcode, users.inter1 AS
users_inter1, users.inter2 AS users_inter2, users.inter3 AS
users_inter3 \nFROM users' ()
The three files I am using are (App.py, models.py, db_create.py)
App.py
from flask import Flask, render_template, request
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mfiyzc.db'
db = SQLAlchemy(app)
if __name__ == "__main__":
app.run(debug = True)
models.py
from app import db
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
zipcode = db.Column(db.Integer, nullable=False)
inter1 = db.Column(db.String, nullable=False)
inter2 = db.Column(db.String, nullable=False)
inter3 = db.Column(db.String, nullable=False)
def __init__(self, name, zipcode, inter1, inter2, inter3):
self.name = name
self.zipcode = zipcode
self.inter1 = inter1
self.inter2 = inter2
self.inter3 = inter3
def __repr__(self):
return '<title {}'.format(self.title)
db_create.py
from app import db
from models import User
db.create_all()
db.session.add(User("Jane Parker", 11104, "ice skating", "dancing", "reading"))
db.session.add(User("Bob Smith", 11104, "boxing", "cars", "beers"))
db.session.commit()
You need to run db_create.py ie :
python db_create.py
or
from models import User
db.create_all()
You are trying to query the table before it has been created.
I had the wrong field name (since I copied from the tutorial)
incorrect:
def __repr__(self):
return '<title {}'.format(self.title)
correct:
def __repr__(self):
return '<name {}'.format(self.name)