SQLAlchemy error patterns improved

SQLite has new error messages since 3.7.16.
DBDuplicateEntry is now recognized correctly.

Change-Id: I86e9673ac409b3b3e881bea7cb8b3516f320388d
Fixes: bug #1259915
This commit is contained in:
Nikita Konovalov 2013-12-11 16:35:54 +04:00
parent 15ea4ffdbc
commit c802fa66f8

View File

@ -439,6 +439,11 @@ def get_session(autocommit=True, expire_on_commit=False,
# 1 column - (IntegrityError) column c1 is not unique # 1 column - (IntegrityError) column c1 is not unique
# N columns - (IntegrityError) column c1, c2, ..., N are not unique # N columns - (IntegrityError) column c1, c2, ..., N are not unique
# #
# sqlite since 3.7.16:
# 1 column - (IntegrityError) UNIQUE constraint failed: k1
#
# N columns - (IntegrityError) UNIQUE constraint failed: k1, k2
#
# postgres: # postgres:
# 1 column - (IntegrityError) duplicate key value violates unique # 1 column - (IntegrityError) duplicate key value violates unique
# constraint "users_c1_key" # constraint "users_c1_key"
@ -451,9 +456,10 @@ def get_session(autocommit=True, expire_on_commit=False,
# N columns - (IntegrityError) (1062, "Duplicate entry 'values joined # N columns - (IntegrityError) (1062, "Duplicate entry 'values joined
# with -' for key 'name_of_our_constraint'") # with -' for key 'name_of_our_constraint'")
_DUP_KEY_RE_DB = { _DUP_KEY_RE_DB = {
"sqlite": re.compile(r"^.*columns?([^)]+)(is|are)\s+not\s+unique$"), "sqlite": (re.compile(r"^.*columns?([^)]+)(is|are)\s+not\s+unique$"),
"postgresql": re.compile(r"^.*duplicate\s+key.*\"([^\"]+)\"\s*\n.*$"), re.compile(r"^.*UNIQUE\s+constraint\s+failed:\s+(.+)$")),
"mysql": re.compile(r"^.*\(1062,.*'([^\']+)'\"\)$") "postgresql": (re.compile(r"^.*duplicate\s+key.*\"([^\"]+)\"\s*\n.*$"),),
"mysql": (re.compile(r"^.*\(1062,.*'([^\']+)'\"\)$"),)
} }
@ -483,10 +489,14 @@ def _raise_if_duplicate_entry_error(integrity_error, engine_name):
# SQLAlchemy can differ when using unicode() and accessing .message. # SQLAlchemy can differ when using unicode() and accessing .message.
# An audit across all three supported engines will be necessary to # An audit across all three supported engines will be necessary to
# ensure there are no regressions. # ensure there are no regressions.
m = _DUP_KEY_RE_DB[engine_name].match(integrity_error.message) for pattern in _DUP_KEY_RE_DB[engine_name]:
if not m: match = pattern.match(integrity_error.message)
if match:
break
else:
return return
columns = m.group(1)
columns = match.group(1)
if engine_name == "sqlite": if engine_name == "sqlite":
columns = columns.strip().split(", ") columns = columns.strip().split(", ")