primary_key = kwargs.pop("primary_key", False)
nullable = kwargs.pop("nullable", Undefined)
foreign_key = kwargs.pop("foreign_key", Undefined)
+ unique = kwargs.pop("unique", False)
index = kwargs.pop("index", Undefined)
sa_column = kwargs.pop("sa_column", Undefined)
sa_column_args = kwargs.pop("sa_column_args", Undefined)
self.primary_key = primary_key
self.nullable = nullable
self.foreign_key = foreign_key
+ self.unique = unique
self.index = index
self.sa_column = sa_column
self.sa_column_args = sa_column_args
regex: Optional[str] = None,
primary_key: bool = False,
foreign_key: Optional[Any] = None,
+ unique: bool = False,
nullable: Union[bool, UndefinedType] = Undefined,
index: Union[bool, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore
regex=regex,
primary_key=primary_key,
foreign_key=foreign_key,
+ unique=unique,
nullable=nullable,
index=index,
sa_column=sa_column,
nullable = not primary_key and _is_field_nullable(field)
args = []
foreign_key = getattr(field.field_info, "foreign_key", None)
+ unique = getattr(field.field_info, "unique", False)
if foreign_key:
args.append(ForeignKey(foreign_key))
kwargs = {
"primary_key": primary_key,
"nullable": nullable,
"index": index,
+ "unique": unique,
}
sa_default = Undefined
if field.field_info.default_factory:
--- /dev/null
+from typing import Optional\r
+\r
+import pytest\r
+from sqlalchemy.exc import IntegrityError\r
+from sqlmodel import Field, Session, SQLModel, create_engine\r
+\r
+\r
+def test_should_allow_duplicate_row_if_unique_constraint_is_not_passed(clear_sqlmodel):\r
+ class Hero(SQLModel, table=True):\r
+ id: Optional[int] = Field(default=None, primary_key=True)\r
+ name: str\r
+ secret_name: str\r
+ age: Optional[int] = None\r
+\r
+ hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")\r
+ hero_2 = Hero(name="Deadpond", secret_name="Dive Wilson")\r
+\r
+ engine = create_engine("sqlite://")\r
+\r
+ SQLModel.metadata.create_all(engine)\r
+\r
+ with Session(engine) as session:\r
+ session.add(hero_1)\r
+ session.commit()\r
+ session.refresh(hero_1)\r
+\r
+ with Session(engine) as session:\r
+ session.add(hero_2)\r
+ session.commit()\r
+ session.refresh(hero_2)\r
+\r
+ with Session(engine) as session:\r
+ heroes = session.query(Hero).all()\r
+ assert len(heroes) == 2\r
+ assert heroes[0].name == heroes[1].name\r
+\r
+\r
+def test_should_allow_duplicate_row_if_unique_constraint_is_false(clear_sqlmodel):\r
+ class Hero(SQLModel, table=True):\r
+ id: Optional[int] = Field(default=None, primary_key=True)\r
+ name: str\r
+ secret_name: str = Field(unique=False)\r
+ age: Optional[int] = None\r
+\r
+ hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")\r
+ hero_2 = Hero(name="Deadpond", secret_name="Dive Wilson")\r
+\r
+ engine = create_engine("sqlite://")\r
+\r
+ SQLModel.metadata.create_all(engine)\r
+\r
+ with Session(engine) as session:\r
+ session.add(hero_1)\r
+ session.commit()\r
+ session.refresh(hero_1)\r
+\r
+ with Session(engine) as session:\r
+ session.add(hero_2)\r
+ session.commit()\r
+ session.refresh(hero_2)\r
+\r
+ with Session(engine) as session:\r
+ heroes = session.query(Hero).all()\r
+ assert len(heroes) == 2\r
+ assert heroes[0].name == heroes[1].name\r
+\r
+\r
+def test_should_raise_exception_when_try_to_duplicate_row_if_unique_constraint_is_true(\r
+ clear_sqlmodel,\r
+):\r
+ class Hero(SQLModel, table=True):\r
+ id: Optional[int] = Field(default=None, primary_key=True)\r
+ name: str\r
+ secret_name: str = Field(unique=True)\r
+ age: Optional[int] = None\r
+\r
+ hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")\r
+ hero_2 = Hero(name="Deadpond", secret_name="Dive Wilson")\r
+\r
+ engine = create_engine("sqlite://")\r
+\r
+ SQLModel.metadata.create_all(engine)\r
+\r
+ with Session(engine) as session:\r
+ session.add(hero_1)\r
+ session.commit()\r
+ session.refresh(hero_1)\r
+\r
+ with pytest.raises(IntegrityError):\r
+ with Session(engine) as session:\r
+ session.add(hero_2)\r
+ session.commit()\r
+ session.refresh(hero_2)\r