I'll acknowledge that this is a strange question before I ask it. I'm wondering if it's possible to replicate Flask / SQL Alchemy class methods using raw SQL instead of using the methods themselves?
Long story short, my teammates and I are taking a database design course, and we're now in the implementation phase where we are coding the app that is based on our DB schema design. We want to keep things simple, so we opted for using Flask in Python. We're following the Flask Mega Tutorial, which is a kickass-tic tutorial explaining how to build a basic site like we're doing. We've just completed Chapter 5: User Logins, and are moving on.
In the app/routes.py script, the tutorial does something to grab the user information. Here's the example login route for the example app:
from flask_login import current_user, login_user
from app.models import User
# ...
@app.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('index'))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid username or password')
return redirect(url_for('login'))
login_user(user, remember=form.remember_me.data)
return redirect(url_for('index'))
return render_template('login.html', title='Sign In', form=form)
The line user = User.query.filter_by(username=form.username.data).first() is what I'm interested in. Basically, that line instantiates the User class, which is a database model from SQL Alchemy, and grabs information about the user from the email address they entered. Calling those methods generates a SQL statement like the following:
SELECT `User`.`userID` AS `User_userID`,
`User`.user_email AS `User_user_email`,
`User`.user_first_name AS `User_user_first_name`,
`User`.user_last_name AS `User_user_last_name`,
`User`.user_password AS `User_user_password`
FROM `User`
WHERE `User`.user_email = '[email protected]'
LIMIT 1
And also some information about the user variable itself:
>>> print(type(user))
<class 'myapp.models.User'>
>>> pp(user.__dict__)
{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x7f5a026a8438>,
'userID': 1,
'user_email': '[email protected]',
'user_first_name': 'SomeFirstName',
'user_last_name': 'SomeLastName',
'user_password': 'somepassword'}
On our project, we're not supposed to be using generated SQL statements like the one that comes from calling query.filter_by(username=form.username.data).first() on the instantiated User class; we should be writing the raw SQL ourselves, which normally doesn't make sense, but in our case it does.
Is this possible?
Userfrom the data. But why would you want to do that?User.query.filter_by(username=form.username.data).first()issues a very, very simpleSELECTquery with aLIMIT 1. Using a manual 'handcrafted' query is not going to improve on that query. Everything SQLAlchemy does is introspectable and adjustable, you can build that same query with the core API or just pass raw SQL to the database connection. But that a) increases development cost, and b) opens you up to security problems if you don't handle untrusted data carefully.