我应该将 Postgres 编码为 运行 作为异常吗?
Should I code Postgres to run into an exception?
我想优化我的 API 对数据库的调用量。但是让 Postgres 运行 进入 Unique Constraint 错误可以吗?例如在注册用户时我有两个选择:
from app.models import Users
from tortoise.exceptions import DoesNotExist
try:
await Users.get(email=email)
raise HTTPException(
status_code=HTTP_400_BAD_REQUEST, detail="User already exists"
)
except DoesNotExist:
user = await Users.create(email, hashed_pw)
这将对数据库进行两次调用,但异常会在 Python 中发生。请注意,在 postgres 端没有抛出任何错误或异常。 Postgres 只是 returns nill,在 python 端被解释为 DoesNotExist。另一个解决方案是:
from app.model import Users
from asyncpg.exceptions import UniqueViolationError
try:
user = await Users.create(email, hashed_pw)
except UniqueViolationError:
raise HTTPException(
status_code=HTTP_400_BAD_REQUEST, detail="User already exists"
)
这只会进行一次数据库调用,但 postgres 数据库会发生错误。显然在我看来第二种实现会更有效率,但是只在 postgres 端创建一个异常可以吗?
只有涉及事务或锁定,您的第一个代码才能可靠地工作。否则,如果两个使用相同电子邮件创建用户的请求(我知道在这种情况下这不太可能)命中您的 API,那么两者都可能得到 DoesNotExist
作为结果并执行 await Users.create(email, hashed_pw)
.这种模式通常是不鼓励的。
对控制流使用异常也经常被视为不好的做法。
你的第二个解决方案很好,尝试创建一个条目并使用 postgres 发出的期望告诉用户已经存在的请求没有问题。
如果你有交易并且你有像 await Users.exists(email=email)
这样 returns true 或 false 的函数,第一个就可以了。
就我个人而言,我更喜欢第二种,因为唯一约束已经做了你想做的检查,但你需要确保你确实检查了你得到的错误消息是否是关于 [= 的唯一键的13=] 而不是关于其他错误。
我想优化我的 API 对数据库的调用量。但是让 Postgres 运行 进入 Unique Constraint 错误可以吗?例如在注册用户时我有两个选择:
from app.models import Users
from tortoise.exceptions import DoesNotExist
try:
await Users.get(email=email)
raise HTTPException(
status_code=HTTP_400_BAD_REQUEST, detail="User already exists"
)
except DoesNotExist:
user = await Users.create(email, hashed_pw)
这将对数据库进行两次调用,但异常会在 Python 中发生。请注意,在 postgres 端没有抛出任何错误或异常。 Postgres 只是 returns nill,在 python 端被解释为 DoesNotExist。另一个解决方案是:
from app.model import Users
from asyncpg.exceptions import UniqueViolationError
try:
user = await Users.create(email, hashed_pw)
except UniqueViolationError:
raise HTTPException(
status_code=HTTP_400_BAD_REQUEST, detail="User already exists"
)
这只会进行一次数据库调用,但 postgres 数据库会发生错误。显然在我看来第二种实现会更有效率,但是只在 postgres 端创建一个异常可以吗?
只有涉及事务或锁定,您的第一个代码才能可靠地工作。否则,如果两个使用相同电子邮件创建用户的请求(我知道在这种情况下这不太可能)命中您的 API,那么两者都可能得到 DoesNotExist
作为结果并执行 await Users.create(email, hashed_pw)
.这种模式通常是不鼓励的。
对控制流使用异常也经常被视为不好的做法。
你的第二个解决方案很好,尝试创建一个条目并使用 postgres 发出的期望告诉用户已经存在的请求没有问题。
如果你有交易并且你有像 await Users.exists(email=email)
这样 returns true 或 false 的函数,第一个就可以了。
就我个人而言,我更喜欢第二种,因为唯一约束已经做了你想做的检查,但你需要确保你确实检查了你得到的错误消息是否是关于 [= 的唯一键的13=] 而不是关于其他错误。