2

How can I modify this example to use a sha256 value for the username field as primary key, instead of the autoincremented index?

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

    def __repr__(self):
        return '<User %r>' % self.username

Example taken from here: http://flask-sqlalchemy.pocoo.org/2.3/quickstart/#a-minimal-application

5
  • 1
    You should never use a hash as a primary key. Hashes are not unique. What is wrong with autoincremented index? That is the best choice for practically every primary key. Commented Aug 19, 2018 at 11:25
  • I don't want to insert duplicate usernames. Commented Aug 19, 2018 at 11:31
  • 1
    If you don't want to insert duplicate usernames, then you have to make the username unique. And you did that already. It is fine the way it is. Commented Aug 19, 2018 at 11:33
  • I want to use a similar table, but with URLs, instead of usernames. URLs can be quite long and I was thinking about TEXT instead of VARCHAR. Commented Aug 19, 2018 at 11:35
  • I've added the unique constraint on the hash_url column. Commented Aug 19, 2018 at 12:07

1 Answer 1

1

There's many ways to do this but the simplest one to get what you want is in your routes.py file:

...
from hashlib import sha256

@app.route('/register') 
def register():

    if form.validate_on_submit():
        username_hash = sha256(form.username.data.encode()).hexdigest()
        user = User(id=username_hash)
     ...

As you can see there's a couple parts to this. The username is usually going to be a str which has to be called encode on to become of type bytes. Then just calling the sha256 from the standard library and hexdigest is the method that returns the value for the hash.

Having a 'unique' hash can be useful but so can having a unique integer id which will not be repeated and can be easily referenced down the line. For debugging and looking up Users in the flask-shell it might be easier to do a lookup by a simple integer rather than other attributes or a hash.

This might be simpler to do:

User.query.get(14)

Than using a hash for primary id.

Sign up to request clarification or add additional context in comments.

1 Comment

I've added the unique constraint on the hash_url column. Thank you for explaining the logic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.