之前的方案虽然能够解决重复性问题,但是没有覆盖到多列同时重复的情况。
比如,我们可以认为用户名是可以重复的。但是用户名和年龄不能同时重复,那么这种情况该怎么解决呢?
之前的代码如下:
from sqlalchemy import select
from sqlmodel import Field, Session, SQLModel, create_engine
# 声明模型
class User(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
# 不能为空,必须唯一
name: str = Field(nullable=False, unique=True)
age: int | None = None
# 创建引擎
engine = create_engine("sqlite:///database.db", echo=True)
# 初始化表
SQLModel.metadata.drop_all(engine)
SQLModel.metadata.create_all(engine)
# 添加用户的方法
def add_user(name: str, age: int):
user = User(name=name, age=age)
with Session(engine) as session:
# 检查是否已存在
statement = select(User).where(User.name == name)
results = session.exec(statement)
db_user = results.first()
print("查询结果:", db_user)
if db_user is not None:
print(f"用户 {name} 已存在")
return
# 执行添加
session.add(user)
session.commit()
# 创建两个名字重复的用户
add_user("张三", 23)
add_user("张三", 24)
# 查询所有用户
with Session(engine) as session:
statement = select(User)
results = session.exec(statement).all()
print(results)
这里我选择在查询条件上加一个条件,查询的时候根据name和age同时查询。
代码改写如下:
from sqlalchemy import select
from sqlmodel import Field, Session, SQLModel, create_engine
# 声明模型
class User(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(nullable=False)
age: int | None = None
# 创建引擎
engine = create_engine("sqlite:///database.db", echo=True)
# 初始化表
SQLModel.metadata.drop_all(engine)
SQLModel.metadata.create_all(engine)
# 添加用户的方法
def add_user(name: str, age: int):
user = User(name=name, age=age)
with Session(engine) as session:
# 检查是否已存在
# statement = select(User).where(User.name == name).where(User.age == age)
statement = select(User).where(User.name == name, User.age == age)
results = session.exec(statement)
db_user = results.first()
print("查询结果:", db_user)
if db_user is not None:
print(f"用户 {name}, {age} 已存在")
return
# 执行添加
session.add(user)
session.commit()
# 创建两个名字重复的用户
add_user("张三", 23)
add_user("张三", 24)
add_user("张三", 24) # 期望第三个才重复
# 查询所有用户
with Session(engine) as session:
statement = select(User)
results = session.exec(statement).all()
print(results)
执行结果如下:
前两次的时候都没有重复,第三次重复了,所以没有写入。
注意,这种情况需要将原来模型中name的unique约束去掉才行。