Please i am having this issue with my first sqlachemy app. I am trying to query the db which is posgres and return a row where it matches . Below is my code.
app.py
from sqlalchemy.orm import sessionmaker
from models.models import Base,User,Product,ProductItem,DATABASE, initialize
engine = DATABASE
Base.metadata.bind = (engine)
DBSession = sessionmaker(bind=engine)
session = DBSession()
....
#app.route('/login', methods = ['GET','POST'])
def login():
form = RegisterForm.LoginForm()
if request.method == 'GET':
return render_template('login.html', form=form)
return authenticate(form = form)
def authenticate(form):
if form.validate_on_submit():
try:
user = session.query(User).filter(User.email == 'xxxx#yahoo.com')
if session.query(exists().where(User.email == form.email.data)).scalar() :
return user.name
except :# models.DoesNotExist:
flash("Your email or password does not match !", "error")
return 'error'
my modules is in a seperate folder modules
modules/modules.py
#declarations
Base = declarative_base()
engine = create_engine('postgresql://postgres:0102443167#localhost:5432/postgres',echo=True)
Base.metadata.bind = (engine)
DBSession = sessionmaker(bind=engine)
session = DBSession()
DATABASE = engine
class User(UserMixin , Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
title = Column(CHAR(3), nullable = False)
fname = Column(String(100), nullable = False)
lname = Column(String(100), nullable = False)
username = Column(String(100), nullable = False, unique = True)
email = Column (String(50), nullable =False, unique = True)
password = Column(String(100), nullable = False)
address = Column(String(250), nullable = False)
state = Column(String(50), nullable = False)
is_Admin = Column(Boolean ,default = False)
is_Logged = Column(Boolean, default = False)
is_Active = Column (Boolean , default = False)
is_Block = Column(Boolean, default = False)
joined_On = Column(ArrowType)
......
My problem is with the app.py authenticate method. The code
user = session.query(User).filter(User.email == form.email.data)
Raise an error. When i check form.email.data return correct string. However when i tried
if session.query(exists().where(User.email == form.email.data)).scalar() :
return 'Ok'
works as expected. It works perfect and thus make me realize the issue might be with my query . I then tried
if session.query(exists().where(User.email == form.email.data)).scalar() :
return user.lname
and it raise error saying user does not have property name which should have. I am confuse. Please how do i query record from my tables ? Any help would be appreciated
You have to get the first object which matches the query so you have to add .first() at the end of the query:
user = session.query(User).filter(User.email == form.email.data).first()
See here more info.
Related
I have code that converts a csv into an sqlalchemy table. When I try and use db.session.add() it creates an entry in the datatable, but the id is null. This stops me from being able to interact with the data. I tried creating a normal SQL alchemy table and was able to insert rows fine, but for whatever reason the way pandas added the table is preventing me from adding more rows to the table. I will attach the relevant code. Let me know if you need more
db = SQLAlchemy()
DB_NAME = "database.db"
app = Flask(__name__)
sslify = SSLify(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db.init_app(app)
class Master(db.Model):
__tablename__ = "Master"
__table_args__ = {'extend_existing':True}
index = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(150))
full_name = db.Column(db.String(150))
serial_number = db.Column(db.String(150))
asset_tag = db.Column(db.Integer)
def __repr__(self):
return '<Comments %r>' % self.id
def __init__(self, username, full_name, serial_number, asset_tag):
self.username = username
self.full_name = full_name
self.serial_number = serial_number
self.asset_tag = asset_tag
file_name = 'master.csv'
df = pd.read_csv(file_name)
df['asset_tag'].fillna('-999', inplace=True)
df['asset_tag'] = df['asset_tag'].astype('int')
df.replace(-999," ",inplace=True)
df.fillna(" ", inplace=True)
df.to_sql(con = app.config['SQLALCHEMY_DATABASE_URI'], index_label='index', name=Master.__tablename__, if_exists='append')
#app.route('/adds', methods = ['GET','POST'])
def adds():
thefullname = request.form.get('add_full')
theuser = request.form.get('add_user')
theasset = request.form.get('add_asset')
theserial = request.form.get('add_serial')
theadd = Master(username = theuser, full_name=thefullname, asset_tag=theasset, serial_number=theserial)
db.session.add(theadd)
db.session.commit()
return render_template('home.html')
I am getting this error. I use flask with sqlalchemy and flask login
function:
def getCoins(id):
userr = User.query.get_or_404(id)
if current_user.adViewStatus == 'done' or current_user.adViewStatus == 'none' or current_user.adViewStatus == 'nope':
return redirect('/coins')
elif current_user.adViewStatus == 'watching':
current_user.points = current_user.points + 25
current_user.adViewStatus = 'doneBoy'
db.session.commit()
return redirect('/youGotTheCoins')
else:
return redirect('/')
view function:
#application.route('/coins/get_more/view_ad/<int:id>', methods=['POST', 'GET'])
#login_required
def getCoins1(id):
return getCoins(id)
db model
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String)
password = db.Column(db.String)
email = db.Column(db.String, unique=True)
connection_type = db.Column(db.String)
school = db.Column(db.String)
real_name = db.Column(db.String)
points = db.Column(db.Integer)
adViewStatus = db.Column(db.String)
viewer = db.Column(db.Integer)
I need a fast answer!
Thanks!
By default, SQL databases usually allow their columns to contain None (or, as SQL calls it, null)
If you never set a user's points value, it will be set to that column's default value - which will usually be null if you haven't specified another one
If you expect some column to always have some value, you'll probably want to set it to not allow null values. In SQLAlchemy, that can be done using the nullable argument to Column, like points = db.Column(db.Integer, nullable=False)
You might also want to look into setting a default value, like points = db.Column(db.Integer, nullable=False, default=0)
I first request is right, But when I second request is wrong. I know the reason get this result is session object expired. But I don't know why? The flowing is my test script.
Detail:
In my actual project, I set a global variable current_user to save the current user, and then add some cache-related attributes to this global variable. The cache-related attributes are actually an object, which is called in the method of the object Pass in the ginseng.
import datetime
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Integer, Column, DateTime, Integer, String, func, VARCHAR
app = Flask(__name__)
app.config[
"SQLALCHEMY_DATABASE_URI"
] = "mysql+mysqlconnector://root:123456#127.0.0.1:3306/pool"
# app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
# In my project I set global var to solve memory leak
current_user = {}
def get_cache(user):
def inner():
class hello:
def get_user_name(self):
# if user not in db.session:
# print("user 已经过期了")
# session_user = db.session.merge(user)
# else:
# session_user = user
# return "%s" % (session_user.username)
return "%s" % (user.username)
return hello()
return inner()
def get_current_user(ticker):
user = current_user.get(ticker)
if user:
return user
user = User.query.first()
current_user[ticker] = user
user.cache = get_cache(user)
return user
class User(db.Model):
__tablename__ = "user"
id = Column(Integer, primary_key=True)
username = Column(String(50), nullable=False, unique=True)
mobile = Column(String(20), nullable=False, unique=True)
password = Column(String(100), nullable=False)
is_admin = Column(Integer, default=0)
created_at = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
updated_at = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
level = Column(Integer, default=1)
remark = Column(String(100), nullable=False)
#app.after_request
def after_request(response):
db.session.rollback()
db.session.remove()
return response
#app.route("/test", methods=["GET"])
def test():
user = get_current_user("ltc")
print(user.username, "这个")
print(user.cache.get_user_name())
return "hello world"
if __name__ == "__main__":
app.run(host="127.0.0.1", port=5000)
My environment:
Flask==1.0.2
Flask-SQLAlchemy==2.3.2
I want to store the details stored in x variable to the sqlite database using flask sqlalchemy. How to make it possible.
Here's the code i wrote:
from flask import Flask
from flask_httpauth import HTTPBasicAuth
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/u.db'
db = SQLAlchemy(app)
class User(db.Model) :
x = ['username = "sam"', 'password = "sam123"']
u1 = (x[0].split()[0])
p1 = (x[1].split()[0])
print(u1,p1)
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key = True)
u1 = db.Column(db.String(32), index = True)
p1 = db.Column(db.String(128))
if __name__ == '__main__':
db.create_all()
print("db created")
app.run(host='0.0.0.0', port=5001)
table created in sqlite:
id u1 p1
Required table to be created in sqlite and data to be loaded:
id username password
1 sam sam123
Your table needs to define the columns with the names that you want:
class User(db.Model) :
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(32), index = True)
password = db.Column(db.String(128))
You can make function to extract the username and password from x:
def get_user_data(data):
user_data = []
for item in data:
part = item.partition(' = ')[2]
cleaned = part.replace('"', '')
user_data.append(cleaned)
return user_data
And create a User instance like this:
username, password = get_user_data(x)
user = User(username=username, password=password)
I have a flask project that I started 5 months ago and stopped after reg and authentication. I now want to proceed, after fresh installations, I am now getting the titled error with the login/authentication. Below
Account form
class LoginForm(Form):
email = StringField('Enter email', validators=[DataRequired(),Email()])
password = PasswordField('Password', validators=[DataRequired()])
remember = BooleanField('Remember Password')
In route file
#app.route('/',methods=['GET', 'POST'])
#app.route('/index', methods=['GET', 'POST'])
def index():
formLogin = AccountForm.LoginForm()
if request.method == 'GET' :
return render_template('index.html',formLogin=formLogin)
if request.method == 'POST' :
if request.form.get('login', None) == 'Login' :
return AccountController.authenticatePopUpLogin(formLogin,'index')
In my accountcontroller
def authenticatePopUpLogin(formLogin,route):
if formLogin.validate_on_submit():
try:
user = session.query(User).filter(User.email == formLogin.email.data).first()
except :# models.DoesNotExist:
flash("Your email or password does not match !", "error")
return render_template('login.html',form=formLogin,formLogin = formLogin)
else :
if check_password_hash(user.password,formLogin.password.data):
My User is imported from my model class
class User(UserMixin , Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
title = Column(CHAR(3), nullable = False)
firstname = Column(String(100), nullable = False)
lastname = Column(String(100), nullable = False)
DateOfBirth = Column(ArrowType, default = arrow.utcnow())
username = Column(String(100), nullable = False, unique = True)
email = Column (String(50), nullable =False, unique = True)
password = Column(String(100), nullable = False)
...
It then throws the error above. I am suspecting the error happens here check_password_hash(user.password,formLogin.password.data):. My form validation works however, it throws error when empty etc.
I confirmed the password field exist in my db as well. Please where do I go wrong?
According to the documentation for first method:
Return the first result of this Query or None if the result doesn’t
contain any row.
So, you have to check if user is None.