いくつかのアカウント作成コードを書き、特定のsqlalchemy例外をキャッチしようとしているため、ユーザーが既存のアカウントに既に関連付けられている電子メールにアカウントを登録するときに、適切なエラーメッセージを返すことができます。なぜsqlalchemy.exc.IntegrityErrorではなくsqlalchemy.exc.ProgrammingErrorが得られますか?
これが起こったときに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": "[email protected]"
}
し、別のuserIdが、同じメールを再び投稿:
{
"userId": "Bob",
"email": "[email protected]"
}
私はIntegrityErrorを高めるために第2のポストを期待するだろうが、私はそれがProgrammingErrorを上げる見ている:
sqlalchemy.exc.ProgrammingError: (pg8000.core.ProgrammingError)
('ERROR',
'23505',
'duplicate key value violates unique constraint "idx_email"',
'Key (email)=([email protected]) 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', '[email protected]')]
私は何をしないのですか?