1
votes

I'm trying to make my own database but I get a TypeError: __ init __() got an unexpected keyword argument 'username'.

I followed documentation and simular stack overflows but I still get the same error. It also doesn't seem to make a difference if I have a constructor init or use the method db.create_all().

What am I doing wrong ? I someone is willing to help me, thank you :)

from flask import Flask, flash, redirect, render_template, request, session, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_session import Session
from passlib.apps import custom_app_context as pwd_context
from tempfile import gettempdir

# configure application
app = Flask(__name__)

#Flask-SQLAlchemy  https://www.tutorialspoint.com/flask/flask_sqlalchemy.htm
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///froshims3.db"
db = SQLAlchemy(app)

# configure session to use filesystem (instead of signed cookies)
app.config["SESSION_FILE_DIR"] = gettempdir()
app.config["SESSION_PERMANENT"] = False
Session(app)

class users(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String)
    hash = db.Column(db.String)

# def __init__(self, username, password):
#   self.username = username
#   self.password = password

#db.create_all()

@app.route("/")
def index():
    return apology("TODO")

@app.route("/register", methods=["GET", "POST"])
def register():
    """Register user."""
    if request.method == "GET":
        # redirect user to register page
        return render_template("register.html")

    else: 
        # query database to see if username doesn't exist.
        rows = db.session.query("SELECT * FROM users WHERE username = :username", username=request.form.get("username"))
        if len(rows) == 1:
            return apology("username already exist")

        # hash: http://stackoverflow.com/questions/7627752/secure-authentication-system-in-python
        hash = pwd_context.encrypt(request.form["password"])
        user = Users(request.form["username"], request.form["dorm"])
        db.session.add(user)
        db.session.commit()
        user_id = db.session.query("SELECT id from users WHERE username = :username", username=request.form.get("username"))
        session["user_id"]= user_id
    return apology("Well Done")
2

2 Answers

1
votes

A couple of things:

  1. You need an __init__() method for your SQLAlchemy class if you want your app to be able to create users from data like you are doing. This is what the error is telling you. (You don't need to bother with it if you're only reading from a table)
  2. I don't know much about db.create_all() because I am always sourcing from external databases, but my understanding is it will create any tables that do not exist, but doesn't overwrite tables that have already been created. So, if your database exists you probably don't need it.
  3. hash is a reserved word. doubt this was messing anything up, but changed it as a matter of best practice. and i changed this to push it into the user model.
  4. You can pull the ID right off the created instance once you've done db.commit() rather than execute another SQL query.
  5. I also changed your query to the "ORM Way" since you are using SQLAlchemy this is how you want to do your SQL.

Updated Code:

from flask import Flask, flash, redirect, render_template, request, session, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_session import Session
from passlib.apps import custom_app_context as pwd_context
from tempfile import gettempdir

# configure application
app = Flask(__name__)

#Flask-SQLAlchemy  https://www.tutorialspoint.com/flask/flask_sqlalchemy.htm
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///froshims3.db"
db = SQLAlchemy(app)

# configure session to use filesystem (instead of signed cookies)
app.config["SESSION_FILE_DIR"] = gettempdir()
app.config["SESSION_PERMANENT"] = False
Session(app)

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String)
    hash = db.Column(db.String)

    def __init__(self, username, password):
      self.username = username
      self.password = password

db.create_all()

@app.route("/")
def index():
    return "TODO"

@app.route("/register", methods=["GET", "POST"])
def register():
    """Register user."""
    if request.method == "GET":
        # redirect user to register page
        return render_template("register.html")

    else:
        # query database to see if username doesn't exist.
        # ORM Way:
        exists = User.query.filter_by(username=request.form.get("username")).count()
        if exists:
            return "username already exists"

        # hash: http://stackoverflow.com/questions/7627752/secure-authentication-system-in-python
        hash_pwd = pwd_context.encrypt(request.form["password"])
        user = User(request.form["username"], hash_pwd)
        db.session.add(user)
        db.session.commit()
        session["user_id"]= user.id
    return "Well Done"
0
votes

@emma I know this question is a year old but for SQLAlchemy error

you have to import those functions in your case

from sqlalchemy import Column, String, Integer

and any other function you want to add, just import them check here