UUID (Universally Unique Identifier)¶
Introduction¶
This guide demonstrates how to implement UUID (Universally Unique Identifier) support in SQLModel, providing a robust method for creating unique identifiers across your database tables. You can read more about UUID in the official Python docs for UUID.
Prerequisites¶
Ensure you have the following installed:
- Python 3.7+
- SQLAlchemy 2.0+
- SQLModel 0.0.20+
Adding UUID Support¶
Defining Models with UUID¶
Pydantic has support for UUIDs
types.
To use UUIDs as primary keys, you need to modify your model definitions to include uuid.UUID
as the type for the ID field. Here's an example for an Item
model.
Info
For the database, SQLModel will use sqlalchemy.sql.sqltypes.Uuid
type.
Item Model with UUID¶
import uuid
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: str | None = None
# Code below omitted 👇
import uuid
from typing import Optional
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: Optional[str] = None
# Code below omitted 👇
👀 Full file preview
import uuid
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: str | None = None
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
def main() -> None:
engine = create_engine("sqlite:///database.db", echo=True)
SQLModel.metadata.create_all(engine)
item_id = create_sample_data_and_return_id(engine)
item = get_item_by_uuid(engine, item_id)
if item:
print(f"Found item: {item.title}")
delete_item_by_uuid(engine, item_id)
if __name__ == "__main__":
main()
import uuid
from typing import Optional
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: Optional[str] = None
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
def main() -> None:
engine = create_engine("sqlite:///database.db", echo=True)
SQLModel.metadata.create_all(engine)
item_id = create_sample_data_and_return_id(engine)
item = get_item_by_uuid(engine, item_id)
if item:
print(f"Found item: {item.title}")
delete_item_by_uuid(engine, item_id)
if __name__ == "__main__":
main()
Working with UUIDs¶
Creating Records with UUIDs¶
When creating an Item
record, the id
field will be automatically populated with a new UUID as default_factory=uuid.uuid4
is set:
# Code above omitted 👆
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
# Code below omitted 👇
# Code above omitted 👆
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
# Code below omitted 👇
👀 Full file preview
import uuid
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: str | None = None
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
def main() -> None:
engine = create_engine("sqlite:///database.db", echo=True)
SQLModel.metadata.create_all(engine)
item_id = create_sample_data_and_return_id(engine)
item = get_item_by_uuid(engine, item_id)
if item:
print(f"Found item: {item.title}")
delete_item_by_uuid(engine, item_id)
if __name__ == "__main__":
main()
import uuid
from typing import Optional
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: Optional[str] = None
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
def main() -> None:
engine = create_engine("sqlite:///database.db", echo=True)
SQLModel.metadata.create_all(engine)
item_id = create_sample_data_and_return_id(engine)
item = get_item_by_uuid(engine, item_id)
if item:
print(f"Found item: {item.title}")
delete_item_by_uuid(engine, item_id)
if __name__ == "__main__":
main()
Info
We are using here uuid.uuid4
as they are safe, enough long and unique to use as a primary key
Querying Records by UUID¶
To query an Item
by its UUID, use the following pattern:
# Code above omitted 👆
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
# Code below omitted 👇
# Code above omitted 👆
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
# Code below omitted 👇
👀 Full file preview
import uuid
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: str | None = None
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
def main() -> None:
engine = create_engine("sqlite:///database.db", echo=True)
SQLModel.metadata.create_all(engine)
item_id = create_sample_data_and_return_id(engine)
item = get_item_by_uuid(engine, item_id)
if item:
print(f"Found item: {item.title}")
delete_item_by_uuid(engine, item_id)
if __name__ == "__main__":
main()
import uuid
from typing import Optional
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: Optional[str] = None
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
def main() -> None:
engine = create_engine("sqlite:///database.db", echo=True)
SQLModel.metadata.create_all(engine)
item_id = create_sample_data_and_return_id(engine)
item = get_item_by_uuid(engine, item_id)
if item:
print(f"Found item: {item.title}")
delete_item_by_uuid(engine, item_id)
if __name__ == "__main__":
main()
Deleting Records by UUID¶
To delete an Item
using its UUID:
# Code above omitted 👆
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
# Code below omitted 👇
# Code above omitted 👆
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
# Code below omitted 👇
👀 Full file preview
import uuid
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: str | None = None
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
def main() -> None:
engine = create_engine("sqlite:///database.db", echo=True)
SQLModel.metadata.create_all(engine)
item_id = create_sample_data_and_return_id(engine)
item = get_item_by_uuid(engine, item_id)
if item:
print(f"Found item: {item.title}")
delete_item_by_uuid(engine, item_id)
if __name__ == "__main__":
main()
import uuid
from typing import Optional
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: Optional[str] = None
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
def main() -> None:
engine = create_engine("sqlite:///database.db", echo=True)
SQLModel.metadata.create_all(engine)
item_id = create_sample_data_and_return_id(engine)
item = get_item_by_uuid(engine, item_id)
if item:
print(f"Found item: {item.title}")
delete_item_by_uuid(engine, item_id)
if __name__ == "__main__":
main()
Example Usage¶
Here's a complete example demonstrating the creation, querying, and deletion of records with UUIDs:
import uuid
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: str | None = None
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
def main() -> None:
engine = create_engine("sqlite:///database.db", echo=True)
SQLModel.metadata.create_all(engine)
item_id = create_sample_data_and_return_id(engine)
item = get_item_by_uuid(engine, item_id)
if item:
print(f"Found item: {item.title}")
delete_item_by_uuid(engine, item_id)
if __name__ == "__main__":
main()
import uuid
from typing import Optional
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Item(SQLModel, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
title: str
description: Optional[str] = None
def create_sample_data_and_return_id(engine) -> uuid.UUID:
with Session(engine) as session:
item = Item(title="Example Item", description="An example item")
session.add(item)
session.commit()
session.refresh(item)
return item.id
def get_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
return item
def delete_item_by_uuid(engine, item_id: uuid.UUID):
with Session(engine) as session:
item = session.exec(select(Item).where(Item.id == item_id)).one_or_none()
session.delete(item)
session.commit()
print("Item deleted successfully.")
def main() -> None:
engine = create_engine("sqlite:///database.db", echo=True)
SQLModel.metadata.create_all(engine)
item_id = create_sample_data_and_return_id(engine)
item = get_item_by_uuid(engine, item_id)
if item:
print(f"Found item: {item.title}")
delete_item_by_uuid(engine, item_id)
if __name__ == "__main__":
main()
Conclusion¶
This guide provided a focused overview of implementing UUID support in SQLModel. By following these steps, you can ensure that your models have robust, unique identifiers, enhancing the reliability and scalability of your application.