fastapi / sqlmodel

SQL databases in Python, designed for simplicity, compatibility, and robustness.
https://sqlmodel.tiangolo.com/
MIT License
14.17k stars 629 forks source link

Generatate composite unique constraints #114

Open cacomop opened 3 years ago

cacomop commented 3 years ago

First Check

Commit to Help

Example Code

from typing import Optional
import datetime
from sqlmodel import SQLModel, Field

class User(SQLModel):
    id: int = Field(primary_key=True)
    name: str = Field(unique=True)
    lastname: str = Field(unique=True)

Description

Operating System

Windows

Operating System Details

No response

SQLModel Version

0.0.3

Python Version

3.8.6

Additional Context

No response

tadejsv commented 3 years ago

Do this

from typing import Optional
import datetime
from sqlalchemy import UniqueConstraint
from sqlmodel import SQLModel, Field

class User(SQLModel):
    __table_args__ = (UniqueConstraint("name", "lastname"), )

    id: int = Field(primary_key=True)
    name: str = Field(unique=True)
    lastname: str = Field(unique=True)
cacomop commented 3 years ago

it works! thank you a lot!

where did you find the solution?

tadejsv commented 3 years ago

Basically, the SQLModel can be treated as a subclass of SQLAlchemy's declarative Base, so everything that works there should work here as well.

Specifically, for __table_args__, see here: https://docs.sqlalchemy.org/en/14/orm/declarative_tables.html#orm-declarative-table-configuration

Trophime commented 2 years ago

It seems to be no longer working with 0.0.4 version:

Traceback (most recent call last):
  File "unique.py", line 6, in <module>
    class User(SQLModel):
  File "unique.py", line 10, in User
    name: str = Field(unique=True)
TypeError: Field() got an unexpected keyword argument 'unique'

@tadejsv can you confirm or not, please?

northtree commented 2 years ago

It seems to be no longer working with 0.0.4 version:

Traceback (most recent call last):
  File "unique.py", line 6, in <module>
    class User(SQLModel):
  File "unique.py", line 10, in User
    name: str = Field(unique=True)
TypeError: Field() got an unexpected keyword argument 'unique'

@tadejsv can you confirm or not, please?

@Trophime This one works for 0.0.4.

    name: str = Field(sa_column_kwargs={"unique": True})
    lastname: str = Field(sa_column_kwargs={"unique": True})
DanLipsitt commented 2 years ago

@northtree I think this would result in two independent constraints rather than a single composite constraint. In other words, it would only allow one record with a given first or last name rather than a given first and last name.

northtree commented 2 years ago

@northtree I think this would result in two independent constraints rather than a single composite constraint. In other words, it would only allow one record with a given first or last name rather than a given first and last name.

If only one single composite unique constraint needed, you just have to define via __table_args

from typing import Optional
import datetime
from sqlalchemy import UniqueConstraint
from sqlmodel import SQLModel, Field

class User(SQLModel):
    __table_args__ = (UniqueConstraint("name", "lastname"), )

    id: int = Field(primary_key=True)
    name: str
    lastname: str
productdevbook commented 2 years ago
CleanShot 2021-12-28 at 20 12 52@2x
clstaudt commented 2 years ago

Whatever the reason for the change may be, I think that Field(unique=True) is far more intuitive, readable and pythonic than Field(sa_column_kwargs={"unique": True}).