假设它是模型定义:
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
account = Column(String(255), unique=True, index=True)
password = Column(String(128))
created_at = Column(DateTime, default=datetime.datetime.utcnow)
updated_at = Column(DateTime, onupdate=datetime.datetime.utcnow,
default=datetime.datetime.utcnow)
假设我已在数据库中插入Tom
但您再次插入它。你更喜欢哪种处理方法?
让它发生错误,然后处理错误。
try:
user = User(account='Tom', ...)
session.add(user)
session.commit()
except:
# do something
<案例B
搜索用户是否存在。如果它不存在,它将创建。
user = session.query(User).filter(User.account == 'Tom').one()
if user:
# do something
user = User(account='Tom', ...)
session.add(user)
session.commit()
哪个更好?
答案 0 :(得分:3)
在Python中,要求宽恕而非许可(EAFP)更为惯用
<强> EAFP 强>: 比许可更容易请求宽恕。这种常见的Python编码风格假设存在有效的键或属性,并且如果假设被证明是错误则捕获异常。这种干净和快速的风格的特点是存在许多try和except语句。该技术与许多其他语言(如C。
)共有的LBYL风格形成对比
来源:https://docs.python.org/3.4/glossary.html
在这方面,你的案例A方法更好。
无论您做什么检查以确保没有重复,您可以在插入时间过时。因此,在您的检查发出绿灯后,您的程序的另一个实例(例如另一个Flask工作人员)会添加一行,这很可能。
这对您来说尤其具有破坏性,因为您的案例B不是,如果该检查清除,则不会发生任何异常,这可能会完全阻止程序的执行。案例A很容易在这里胜出。
此外,您的第二个方法始终发生在两个查询中(一个用于检查,一个用于添加),而第一个方法仅在重复的情况下抛出异常
所以我说你的案例A更好(只有在有重复时处理例外的案例)
我看到的唯一的挑剔是你应该 NOT 使用except:
(太宽的网),但是使用一个特殊的异常,当你插入一个重复的行时会抛出。
假设在这种情况下抛出的是IntegrityError
,我们应该
try:
# Insert a potentially duplicate row
except IntegrityError:
# Deal with the case
答案 1 :(得分:1)
在Web应用程序开发中,您需要随着时间的推移增强应用程序,减少数据库查询是您在一段时间内需要的增强功能之一。因此案例A比案例B更好。因为如果找不到用户,它只运行一个查询(1个查询来更新数据)如果找不到使用(1个查询要创建)。
我还想推荐Daniel Roy Greenfeld和Audrey Roy Greenfeld以及Peter Baumgartner和Yann Malet撰写的关于Django Web应用程序开发的杰出书籍Two Scoops of Django
。