Sqlalchemy ProgrammingError exception: Unknown column - python

here are the files which contain my code:
this is models.py file
from . import db
from flask_login import UserMixin
from sqlalchemy 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))
notes = db.relationship('Note')
class Note(db.Model):
time = func.now()
id = db.Column(db.Integer, primary_key=True)
data = db.Column(db.String(1000))
date = db.Column(db.DateTime(timezone=True), default=time)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
and this is views.py
from flask import Blueprint, render_template, request
from flask_login import login_required, current_user
from .models import Note
from . import db
views = Blueprint('views', __name__)
#views.route('/notes', methods=['GET', 'POST'])
#login_required
def notes():
if request.method == 'POST':
note = request.form.get('note')
new_note = Note(data=note, user_id=current_user.id)
db.session.add(new_note)
db.session.commit()
return render_template('notes.html', user=current_user)
I got the error
sqlalchemy.exc.ProgrammingError:
(mysql.connector.errors.ProgrammingError) 1054 (42S22): Unknown column
'user_id' in 'field list' [SQL: INSERT INTO note (id, data, date,
user_id) VALUES (%(id)s, %(data)s, now(), %(user_id)s)] [parameters:
{'id': 1, 'data': 'get a ', 'user_id': None}]
Any idea on where I messed
up and how to fix it ?

I just fixed a problem similar to this. My code was trying to insert one of the Column values into one of the Column names. Like the others have suggested, examine your code within the database. Here are some examples of my code before and after:
incorrect variable: self.all_output_data
self.user_tables = f"""
INSERT INTO voicechannel_{self.my_name_and_id}
(my_input, msg_from_input, self.all_output_data, my_output)
VALUES
('{self.my_input_widget}','{self.all_input_data[0]}',
'{self.all_output_data}','{self.output_to_other_nodes[0]}')
"""
correct variable: msg_to_output
self.user_tables = f"""
INSERT INTO voicechannel_{self.my_name_and_id}
(my_input, msg_from_input, msg_to_output, my_output)
VALUES
('{self.my_input_widget}','{self.all_input_data[0]}',
'{self.all_output_data}','{self.output_to_other_nodes[0]}')
"""

Change this line of code from
new_note = Note(data=note, id=current_user.id)
to
new_note = Note(data=note, user_id=current_user.id)

Related

SQL Integrity Error While adding a multiple values to a table in Flask App

I am creating a Flask App using MYSQL Database. The code seems legit from tutorial and online search I am following but the "Create user function didn't work properly. The error always comes back with missing user_id value although I am adding it. Help me through this I am stuck with over 5 days with this error
db = SQLAlchemy(app)
#database connection
class friends(db.Model):
__tablename__ = 'user'
user_id = db.Column(db.String, primary_key=True)
user_name = db.Column(db.String)
age = db.Column(db.Integer)
email = db.Column(db.String)
gender = db.Column(db.String)
def __init__(self, user_id, user_name, age, email,gender):
self.id = user_id
self.name = user_name
self.age = age
self.email = email
self.gender = gender
#route
#app.route('/add', methods=['GET', 'POST'])
def add():
if request.method == 'POST':
add_usr_id = request.form['new_usr_id']
add_usr_name = request.form['new_usr_name']
add_usr_age = request.form['new_usr_age']
add_usr_email = request.form['new_usr_email']
add_usr_gender = request.form['new_usr_gender']
commit_user = friends(user_id = add_usr_id, user_name = add_usr_name, age = add_usr_age, email = add_usr_email, gender = add_usr_gender)
db.session.add(commit_user)
db.session.commit()
message = "The record was added."
return render_template('add.html', message=message)
else:
return render_template('add.html')
#app.route('/show')
def read():
show_friend = friends.query.all()
return render_template('show.html', show_friend = show_friend)
This is the full error traceback :
sqlalchemy.exc.IntegrityError: (pymysql.err.IntegrityError) (1048, "Column 'user_name' cannot be null")
[SQL: INSERT INTO user (user_name, age, email, gender) VALUES (%(user_name)s, %(age)s, %(email)s, %(gender)s)]
[parameters: {'user_name': None, 'age': '32', 'email': 'dfak#ekfl.com', 'gender': 'male'}]
(Background on this error at: https://sqlalche.me/e/14/gkpj)
> add_usr_id = request.form['new_usr_id']
Add a debug print or logging statement there.
It will reveal that None was passed in.
Either arrange for a better value to be
presented, or hack in some default value.
Here is one way to default it:
add_usr_id = request.form['new_usr_id'] or 'default_user'

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: student.email

I have a registration form and am trying to add student data to the database model(Student) but i get this error upon submiting the form data
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: student.email
[SQL: INSERT INTO student (username, email, image_file, password) VALUES (?, ?, ?, ?)]
[parameters: ('elijah', 'elijah#gmail.com', 'default.jpg', '$2b$12$lo4MLsE/hdI6SOnUr3lg5eg02u.u5xfRJYwKQzMn3bohXglif/73S')]
(Background on this error at: https://sqlalche.me/e/14/gkpj)
Am not sure of what's causing the error, have tried dropping and recreating my database modles again but the error persists.
This is my student model where the error is pointing to student.email
from datetime import datetime
from ..utils.db import db
class Student(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(255), nullable=True, default='default.jpg')
password = db.Column(db.String(120), nullable=False)
student_mark = db.relationship('Mark', backref='mark')
student_qn = db.relationship('StudentQuestion',backref='examinee')
def __repr__(self):
return f"Student('{self.username}', '{self.email}')"
def save(self):
db.session.add(self)
db.session.commit()
and this is the route that has the submission form which throws the error after i insert data into the form
from flask import render_template, url_for, flash, redirect, Blueprint
from .registerform import RegistrationForm
from flask_bcrypt import Bcrypt
from ..models.models import Student
from ..utils.db import db
bcrypt = Bcrypt()
register_route = Blueprint('register_route', __name__)
#register_route.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
student= Student(username=form.username.data, email=form.email.data, password=hashed_password)
db.session.add(student)
db.session.commit()
flash(f'Welcome {form.username.data} ,your can now login!')
return redirect(url_for('login_route.login'))
return render_template('register.html', title='RegisterPage', form=form)
What could be the problem and how can i avoid it!

Passing different form data entries to the same row in a database with Python Flask and SQLAlchemy

I've created a form which takes user's name and their email address. I get this data from the form and put it into a sqlite3 database in the following way:
#app.route('/my_form', methods=["GET", "POST"])
def form_data():
if request.method == "POST":
user_name = request.form["name"]
new_user = form_database(name=user_name)
user_email = request.form["email"]
new_user_email = form_database(email=user_email)
try:
db.session.add(new_user)
db.session.add(new_user_email)
db.session.commit()
return redirect("/my_form")
Current result: each data entry gets recorded into a new row:
1|Jack||||||||||
2||svisto#hotmail.com|||||||||
Desirable result: each data entry gets recorded into the same row:
1|Jack|svisto#hotmail.com|||||||||
Question: How can I change the code such that I get the desirable result?
Lets say you have a User class in your model like this:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer,
primary_key=True)
username = db.Column(db.String(32),
index=False,
unique=True,
nullable=False)
email = db.Column(db.String(64),
index=True,
unique=True,
nullable=False)
Then you can do this in your try block
try:
new_user = User(user_name=user_name,
email=email)
db.session.add(new_user)
db.session.commit()
Solution I found:
I fused:
new_user = form_database(name=user_name) and new_user_email = form_database(email=user_email)
together such that the code looks like this:
#app.route('/my_form', methods=["GET", "POST"])
def form_data():
if request.method == "POST":
user_name = request.form["name"]
user_email = request.form["email"]
new_user_details = form_database(name=user_name, email=user_email)#assigns 2 form inputs for both columns in the database model to the same variable
try:
db.session.add(new_user_details)#adds that variable to the database as one entry, hence in one row but different columns
db.session.commit()

Flask/Python: Sqlalchemy.exc.OperationalError

I am new in Flask and I am trying to create a blog. I want to create a page from where I would like to insert the posts. In theory, the page should redirect to the index but every time I try to insert content in the page "add" I get an error. Here is my code:
from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////Users/admin/Desktop/Blog_Project/blog2.db'
db = SQLAlchemy(app)
class Blogpost(db.Model):
id = db.Column(db.Integer, primary_key = True)
title = db.Column(db.String(50))
subtitle = db.Column(db.String(50))
author = db.Column(db.String(20))
date_posted = db.Column(db.DateTime)
content = db.Column(db.Text)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/about')
def about():
return render_template('about.html')
#app.route('/post')
def post():
return render_template('post.html')
#app.route('/contact')
def contact():
return render_template('contact.html')
#app.route('/prova')
def prova():
return render_template('prova.html')
#app.route('/add')
def add():
return render_template('add.html')
#app.route('/addpost', methods=['POST'])
def addpost():
title = request.form['title']
subtitle = request.form['subtitle']
author = request.form["author"]
content = request.form['content']
post = Blogpost(title=title, subtitle=subtitle, author=author, content=content, date_posted = datetime.now())
db.session.add(post)
db.session.commit()
return redirect(url_for('index'))
if __name__ == "__main__":
app.run(debug = True)
And this is the error I get:
sqlalchemy.exc.OperationalError
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: blogpost
[SQL: INSERT INTO blogpost (title, subtitle, author, date_posted, content) VALUES (?, ?, ?, ?, ?)]
[parameters: ('ds', 'ds', 'sd', '2020-09-08 12:55:25.333277', 'ds')]
(Background on this error at: http://sqlalche.me/e/13/e3q8)
As far as I understand, the problem is that Flask cannot create the table blogpost in the database blog2 and fill it with the values that I inserted in the code. I have read some documentation in internet and in Stackoverflow and apparently some people fixed the same problem using the method db.create_all() but I am not sure where I should insert it or if I should reorganize the code in another way. Have you got any suggestion? Thank you very much in advance!

Eve Authentication with bcrypt driver.db error when sending curl request

I use bcrypt for the authentication of my resources and have accounts stored in mydatabase with username and passwords. I have stored the passwords manually as hashes in the database as follows:
I started the python bash and typed in following code:
import bcrypt
password = u'passwordtobehashed'
password_hashed = bcrypt.hashpw(password, bcrypt.gensalt())
print (password_hashed)
Then i copied the output of print and stored it in the account table via a POST Request(w/o authentication):
curl -d '{"username": "someuser", "password": "somehashedpassword", "roles_id": 1}' -H 'Content-Type: application/json' http://127.0.0.1:5000/account
Well I use SQLAlchemy and eve is also up to date (Version: 0.7.1).
Well I request for example the people resource using Bcrypted Authentication as follows:
curl -u username 127.0.0.1:5000/people
Then I enter my password and I get following error:
File "/home/vagrant/erpghost/restapi/oldtrivial.py", line 57, in check_auth
accounts = app.data.driver.db['account']
AttributeError: 'SQLAlchemy' object has no attribute 'db'
For some reason the db attribute is not available. I also tried to use Eve.app.data.driver.db and I tried importing current_app from flask but that all did not work.
Well here is my code:
oldtrivial.py
from eve.auth import BasicAuth
from eve import Eve
from eve_sqlalchemy import SQL
from eve_sqlalchemy.validation import ValidatorSQL
import bcrypt
from connection import connect
from connection import Base
con, meta = connect()
Base.metadata.create_all(con)
class BCryptAuth(BasicAuth):
def check_auth(self, username, password, allowed_roles, resource, method):
accounts = app.data.driver.db['account']
account = accounts.find_one({'username': username})
return account and \
bcrypt.hashpw(password, account['password']) == account['password']
app = Eve(validator=ValidatorSQL, data=SQL, auth=BCryptAuth)
db = app.data.driver
Base.metadata.bind = db.engine
db.Model = Base
db.create_all()
if __name__ == '__main__':
app.run(debug=True, use_reloader=False)
tables.py
from sqlalchemy.orm import column_property
from sqlalchemy import Column, Integer, String, DateTime, func, ForeignKey
from connection import connect
from eve.auth import BasicAuth
from connection import Base
from sqlalchemy.orm import relationship
con, meta = connect()
class CommonColumns(Base):
__abstract__ = True
_created = Column(DateTime, default=func.now())
_updated = Column(DateTime, default=func.now(), onupdate=func.now())
_etag = Column(String(40))
class People(CommonColumns):
__tablename__ = 'people'
_id = Column(Integer, primary_key=True, autoincrement=True)
firstname = Column(String(80))
lastname = Column(String(120))
fullname = column_property(firstname + " " + lastname)
class Roles(CommonColumns):
__tablename__ = 'roles'
_id = Column(Integer, primary_key=True, autoincrement=True)
role = Column(String(80))
class Account(CommonColumns):
__tablename__ = 'account'
_id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(50), nullable=False, unique=True)
password = Column(String(200), nullable=False)
roles = relationship("Roles", backref="account")
roles_id = Column(Integer, ForeignKey('roles._id'))
settings.py
from eve_sqlalchemy.decorators import registerSchema
from eve.utils import config
from tables import People
from tables import Account
from tables import Roles
registerSchema('people')(People)
registerSchema('roles')(Roles)
registerSchema('account')(Account)
DOMAIN = {
'people': People._eve_schema['people'],
'roles': Roles._eve_schema['roles'],
'account': Account._eve_schema['account'],
}
DOMAIN['account'].update({
'additional_lookup': {
'url': 'regex("[\w]+")',
'field': 'username'
},
'cache_control': '',
'cache_expires': 0,
'allowed_roles': ['superuser', 'admin'],
'authentication': None,
})
SQLALCHEMY_DATABASE_URI = 'postgresql://databaseuser:password#localhost:5432/database'
RESOURCE_METHODS = ['GET', 'POST']
ITEM_METHODS = ['GET', 'DELETE', 'PATCH', 'PUT']
DEBUG = True
config.ID_FIELD = config.ITEM_LOOKUP_FIELD = '_id'
DOMAIN['people']['id_field'] = config.ID_FIELD
DOMAIN['roles']['id_field'] = config.ID_FIELD
DOMAIN['account']['id_field'] = config.ID_FIELD
Hope someone can help me out.
Something along these lines should work:
from flask import current_app
from tables import Account
# ...
def check_auth(...):
session = current_app.data.driver.session
return session.query(Account) \
.filter(Account.username == username,
Account.password == hashed_password) \
.count() > 0
I guess you've tried to mimic the code in http://python-eve.org/authentication.html#basic-authentication-with-bcrypt ? This is for using Mongo-DB instead of SQLAlchemy.

Categories

Resources