17

I'm trying to create objects in Postgres db.

I'm using this approach https://websauna.org/docs/narrative/modelling/models.html#uuid-primary-keys

class Role(Base):
    __tablename__ = 'role'

    # Pass `binary=False` to fallback to CHAR instead of BINARY
    id = sa.Column(UUIDType(binary=False), primary_key=True)

But when I create object

user_role = Role(name='User')
db.session.add(user_role)
db.session.commit()

I have the following error:

sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError) null value in column "id" violates not-null constraint

Looks like I didn't provide any ID. So, how I can make the database auto-generate it or generate on my own?

1

4 Answers 4

33

You appear to be using this code. It's missing a default for the column. You're emulating this SQL:

id UUID PRIMARY KEY DEFAULT uuid_generate_v4()

But you've already linked to the correct code.

id = Column(UUID(as_uuid=True),
    primary_key=True,
    server_default=sqlalchemy.text("uuid_generate_v4()"),)

Alternatively if you don't want to load a Postgres UUID extension, you can create the UUIDs in Python.

from uuid import uuid4

id = Column(UUID(as_uuid=True),
    primary_key=True,
    default=uuid4,)
Sign up to request clarification or add additional context in comments.

1 Comment

For Postgres 13+ we no longer need to use the uuid-ossp extension and can instead use the built-in gen_random_uuid()
5

You could use the uuid module and just set a column default. For example:

from uuid import uuid4
from sqlalchemy import Column, String

class Role(Base):
    __tablename__ = 'role'

    id = Column(String, primary_key=True, default=uuid4)

1 Comment

If you are looking to use the PostgreSQL UUID type (which I believe has some performance advantages), see the answer from @Schwern.
2

What I actually came to is:

import uuid

class SomeClass(db.Model):
    __tablename__ = 'someclass'

    id = db.Column(UUID(as_uuid=True),
        primary_key=True, default=lambda: uuid.uuid4().hex)

1 Comment

Downvoted because this is confusing: you explicitely say you want a UUID type with as_uuid=True, but you provide a default function that returns an str.
-4
import uuid

myId = uuid.uuid4()
print(myId)

Comments

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.