gpt4 book ai didi

python - 为什么我得到的是 sqlalchemy.exc.ProgrammingError 而不是 sqlalchemy.exc.IntegrityError?

转载 作者:太空宇宙 更新时间:2023-11-03 14:59:40 46 4
gpt4 key购买 nike

我正在编写一些帐户创建代码并 try catch 特定的 sqlalchemy 异常,以便当用户使用已关联到现有帐户的电子邮件注册帐户时,我可以反馈适当的错误消息。

发生这种情况时,我原以为会得到一个 IntegrityError,但我却得到了一个 ProgrammingError。我可以很高兴地捕获 ProgrammingError,但我试图理解为什么我没有得到我期望的结果。

为了清晰起见,我已经削减了模型和代码,但模型看起来像:

from service import db
from sqlalchemy import Index

class UserProfile(db.Model):
user_id = db.Column(db.String(255), nullable=False, primary_key=True)
email = db.Column(db.String(255), nullable=False)

def __init__(self, account_data):
self.user_id = account_data['userId']
self.email = account_data['email'].lower()

def __repr__(self):
return 'UserID-{}, Email-{}'.format(self.user_id,self.email)

Index('idx_email', UserProfile.email, unique=True)

代码的主要部分如下所示:

@app.route('/create_account', methods=['POST'])
def create_account():

account_data = request.get_json()

account_details = UserProfile(account_data)
try:
db.session.add(account_details)
db.session.flush()

# do stuff

db.session.commit()

except ProgrammingError as err:
db.session.rollback()
if "duplicate key value violates unique constraint \"idx_email\"" in str(err):
LOGGER.error('Email address already in use!'

例如,如果我在一些 json 中发布:

{
"userId": "Fred",
"email": "a@b.com"
}

然后使用不同的用户 ID 但相同的电子邮件再次发布:

{
"userId": "Bob",
"email": "a@b.com"
}

我希望第二篇文章引发 IntegrityError 但我看到它引发了 ProgrammingError:

sqlalchemy.exc.ProgrammingError: (pg8000.core.ProgrammingError)
('ERROR',
'23505',
'duplicate key value violates unique constraint "idx_email"',
'Key (email)=(a@b.com) already exists.',
'public',
'user_profile',
'idx_email',
'nbtinsert.c',
'406',
'_bt_check_unique', '', '')
[SQL: 'INSERT INTO user_profile (user_id, email) VALUES (%s, %s)']
[parameters: ('Bob', 'a@b.com')]

我错过了什么?

最佳答案

不幸的是,当涉及到 DBAPI 时errors SQLAlchemy 仅包装由底层 dbapi 兼容库引发的异常。

也就是说,SQLAlchemy 引发了一个ProgrammingError,特别是因为pg8000 选择引发一个ProgrammingError

如果您一直在使用 psycopg2 来管理您的底层连接,您的错误将表现为 IntegrityError(正如预期的那样)。

根据pg8000 documentation ,它永远不会引发 IntegrityError。事实上,它不会引发以下任何情况:

  • 完整性错误;
  • 数据错误;
  • 数据库错误;
  • 操作错误;

这里的教训是,当涉及到数据库级错误时,您无法保证 SQLAlchemy 将在不同的 dbapi 连接器上抛出的类型。

关于python - 为什么我得到的是 sqlalchemy.exc.ProgrammingError 而不是 sqlalchemy.exc.IntegrityError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39156330/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com