Search code examples
pythonflaskdeployment

Can we set a default uuid for the id field primary key in a Flask model


I am creating a dynamic website using Flask. Can I set a default value for the id fields of the models so that it gets automatically filled using a uuid value.

class User(db.Model, UserMixin):
    id = db.Column(db.String(36), primary_key=True)
    email = db.Column(db.String(150), unique=True, nullable=False)
    password = db.Column(db.String(255), nullable=False)
    first_name = db.Column(db.String(150), nullable=False)
    last_name = db.Column(db.String(150), nullable=False)
    image_file = db.Column(db.String(60), nullable=False, default='default.jpg')
    created_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)

The above given is my user model and I've set the id field as a string field instead of the default integer field. Can I add a uuid value as the default value in this id field.

I tried giving server_default arg for the id field as a uuid4 value. id = db.Column(db.String(36), primary_key=True, server_default=str(uuid.uuid4()))

But the above code set a single uuid value for the entire column. The properties of the id field in the MySQL database showed the following values:

# Field, Type, Null, Key, Default, Extra
'id', 'varchar(36)', 'NO', 'PRI', 'e3c56759-cc55-46f8-b6d1-d54bd267cf4b', ''

Solution

  • You could try something like this:

    class User(db.Model, UserMixin):
        id = Column(String(36), default=lambda: str(uuid.uuid4()), unique=True)
        email = db.Column(db.String(150), unique=True, nullable=False)
        password = db.Column(db.String(255), nullable=False)
        first_name = db.Column(db.String(150), nullable=False)
        last_name = db.Column(db.String(150), nullable=False)
        image_file = db.Column(db.String(60), nullable=False, default='default.jpg')
        created_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), nullable=False)
        updated_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
    

    The important part here is to pass lambda function as a default value, so the value will be evaluated every time the model is instantiated.