0

i have been developing a flask app with a sqlite3 database. Now to publish it online i am switching the database from sqlite3 to Sqlalchemy and i am very lost. I implemented a login and registrer but i have problems with login. I have to check that the username entered is indeed registered and that the password match the one in the database

I have already created the table:

class Usuarios(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    hash = db.Column(db.String(120), unique=True, nullable=False)
    provincia = db.Column(db.String(80))
    mail = db.Column(db.String(80), nullable=False)
    def __init__(self, username, hash, provincia, mail):
        self.username = username
        self.hash = hash
        self.provincia = provincia
        self.mail = mail

And here is my code:

@app.route("/login", methods=["GET", "POST"])
def login():
    """Log user in"""

    # Forget any user_id
    session.clear()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":
        username=request.form.get("username").upper()

        # Ensure username was submitted
        if not request.form.get("username"):
            return apology("Debe ingresar un nombre de usuario.", 403)

        # Ensure password was submitted
        elif not request.form.get("password"):
            return apology("Debe ingresar una contraseña.", 403)

        # Query database for username

        rowpass = db.session.query.filter_by(Usuarios.username = username).all()
        rows = Usuarios.query.filter_by(username=username).first()

        # Ensure username exists and password is correct
        if rows is None or not check_password_hash(rows[0]["hash"], request.form.get("password")):
            return apology("Usuario o contraseña incorrectos", 403)

        # Remember which user has logged in
        session["user_id"] = rowpass[0]["username"]

        # Redirect user to home page
        return redirect("/")

    # User reached route via GET (as by clicking a link or via redirect)
    else:
        return render_template("login.html")

With in sqlite3 this code worked perfectly but now i dont know how to translate it properly to sqlalchemy:

rows = db.execute("SELECT * FROM usuarios WHERE username = :username",
                         username=request.form.get("username").upper())
if len(rows) != 1 or not check_password_hash(rows[0]["hash"], request.form.get("password")):
    return apology("Usuario o contraseña incorrectos", 403)

I think the problem is in the password check, where i left the sqlite3's square brackets[] and i am not sure if they re used in alchemy. If that is the error i am not sure that the line that says:

session["user_id"] = rows[0]["username"] is correct too

What do you think?

deloco
  • 43
  • 8
  • 1
    This line here: `rows = Usuarios.query.filter_by(username=username).first()` doesn't return a tuple, it returns an instance of `Usuarios`. So it would make more sense to call the variable `user`, i.e. `user = Usuarios.query.filter_by(username=username).first()`. Then you use the usual python object dot notation to get at its attributes, e.g. `check_password_hash(user.hash, request.form.get("password"))`. Also, You don't need the `rowpass = ...` query, `session["user_id"] = user.username` provides the username of the authenticated user. – SuperShoot Aug 12 '19 at 22:46
  • Thanks, this solved it. I have one more problem. I want to view the complete database in the Powershell (terminal). So i do start python and import the db from app. But when i type ```Usuarios.query.all()``` it just return me the "Usuarios+id": ```[, , ] ``. But i want to access all the data inside. Which is the command to view the colums and the rows. In sqlite3 i just had to do SELECT* and everything popped up. I am confused – deloco Aug 13 '19 at 17:58
  • What you are seeing from your query is the value returned from the [`__repr__()`](https://stackoverflow.com/a/1984177/6560549) method of each object that represents a row returned by your query. You should read this: https://stackoverflow.com/q/5632677/6560549 – SuperShoot Aug 14 '19 at 01:25

0 Answers0