mysql 服务器没有 return 完整的错误信息
mysql server does not return full error message
我正在尝试使用 mysql-python-client 编写一个递归函数来删除记录:每次函数调用都取决于最后一个 returning IntegrityError
消息,可用于创建要执行的新 sql。一开始,代码 运行 很顺利,但它以 AssertionError
停止,这是由于 err
不是完整的信息,例如:
Cannot delete or update a parent row: a foreign key constraint fails (`db_name`.`a_table_name`, CONSTRAINT `FK_xxx` FOREIGN KEY (`foreign_key_name`) REFERENCES `incomplete_reference_table_name)
.
那么,为什么错误消息不完整以及如何使其 return 成为完整的消息?
附加信息:我尝试使用 golang>"github.com/go-sql-driver/mysql"
甚至 navicat IDE 结果都是一样的。好像是服务端的BUG?
更新:
CLI 测试结果:
在文本中使用 CLI 测试结果:
mysql> delete from `bnb_system`.`traveler_checkin_handle_record` where `room_id` in (select `id` from `room` where `fk_roomtype_rooms` in (select `id` from `room_type` where `fk_inn_roomtype` in (select `id` from `inn` where landlord_id in (select id from landlord where user_id in (select id from user where tel='15779313733')))));
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`bnb_system`.`concerned_checkin_traveler_check_in_handle_record`, CONSTRAINT `FKc2166ey4rteqht79ahel72scu` FOREIGN KEY (`traveler_check_in_handle_record_id`) REFERENCES `traveler_checkin_handl)
import mysql.connector
import re
host = "some_host"
user = "some_user"
password = "some_pwd"
database = "some_system"
conn = mysql.connector.connect(host=host,
user=user,
password=password,
database=database)
cur = conn.cursor()
org_sql = "some_sql"
def recursive_delete(sql, cur, conn):
sql_post = sql[sql.index('where'):]
try:
print(sql)
cur.execute(sql)
conn.commit()
except mysql.connector.IntegrityError as e:
err = e.msg
print(err)
ss = r'`[\w_]+`'
info = re.findall(ss, err)
assert len(info) == 6, "error message: {}".format(err)
db, table, foreign_key, reference_table, reference_key = info[0], info[1], info[3], info[4], info[5]
new_sql = "delete from {db}.{table} where {foreign_key} in (select {reference_key} from {reference_table} {sql_post})".format(db=db, table=table, foreign_key=foreign_key, reference_key=reference_key, reference_table=reference_table, sql_post=sql_post)
recursive_delete(sql=new_sql, cur=cur, conn=conn)
recursive_delete(sql=org_sql, cur=cur, conn=conn)
最后,我更改了information_schema
中如何查询引用表的实现,解决了问题。
def recursive_delete(all_sql, cur, conn):
for sql in all_sql[::-1]:
sql_post = sql[sql.index('where'):]
try:
print(sql)
cur.execute(sql)
conn.commit()
except mysql.connector.IntegrityError as e:
err = e.msg
ss = r'`([\w_]+)`'
info = re.findall(ss, err)
db, table, constraint_name, foreign_key = info[0], info[1], info[2], info[3]
sql_reference_table_and_reference_key = 'select REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.KEY_COLUMN_USAGE where TABLE_NAME="{table}" and CONSTRAINT_NAME="{constraint_name}" and COLUMN_NAME="{foreign_key}"'.format(table=table, constraint_name=constraint_name,
foreign_key=foreign_key)
print(sql_reference_table_and_reference_key)
cur.execute(sql_reference_table_and_reference_key)
result = cur.fetchone()
reference_table, reference_key = result[0], result[1]
new_sql = "delete from {db}.{table} where {foreign_key} in (select {reference_key} from {reference_table} {sql_post})".format(db=db, table=table, foreign_key=foreign_key, reference_key=reference_key, reference_table=reference_table, sql_post=sql_post)
sql_strings.append(new_sql)
recursive_delete(all_sql=all_sql, cur=cur, conn=conn)
我正在尝试使用 mysql-python-client 编写一个递归函数来删除记录:每次函数调用都取决于最后一个 returning IntegrityError
消息,可用于创建要执行的新 sql。一开始,代码 运行 很顺利,但它以 AssertionError
停止,这是由于 err
不是完整的信息,例如:
Cannot delete or update a parent row: a foreign key constraint fails (`db_name`.`a_table_name`, CONSTRAINT `FK_xxx` FOREIGN KEY (`foreign_key_name`) REFERENCES `incomplete_reference_table_name)
.
那么,为什么错误消息不完整以及如何使其 return 成为完整的消息?
附加信息:我尝试使用 golang>"github.com/go-sql-driver/mysql"
甚至 navicat IDE 结果都是一样的。好像是服务端的BUG?
更新:
CLI 测试结果:
mysql> delete from `bnb_system`.`traveler_checkin_handle_record` where `room_id` in (select `id` from `room` where `fk_roomtype_rooms` in (select `id` from `room_type` where `fk_inn_roomtype` in (select `id` from `inn` where landlord_id in (select id from landlord where user_id in (select id from user where tel='15779313733')))));
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`bnb_system`.`concerned_checkin_traveler_check_in_handle_record`, CONSTRAINT `FKc2166ey4rteqht79ahel72scu` FOREIGN KEY (`traveler_check_in_handle_record_id`) REFERENCES `traveler_checkin_handl)
import mysql.connector
import re
host = "some_host"
user = "some_user"
password = "some_pwd"
database = "some_system"
conn = mysql.connector.connect(host=host,
user=user,
password=password,
database=database)
cur = conn.cursor()
org_sql = "some_sql"
def recursive_delete(sql, cur, conn):
sql_post = sql[sql.index('where'):]
try:
print(sql)
cur.execute(sql)
conn.commit()
except mysql.connector.IntegrityError as e:
err = e.msg
print(err)
ss = r'`[\w_]+`'
info = re.findall(ss, err)
assert len(info) == 6, "error message: {}".format(err)
db, table, foreign_key, reference_table, reference_key = info[0], info[1], info[3], info[4], info[5]
new_sql = "delete from {db}.{table} where {foreign_key} in (select {reference_key} from {reference_table} {sql_post})".format(db=db, table=table, foreign_key=foreign_key, reference_key=reference_key, reference_table=reference_table, sql_post=sql_post)
recursive_delete(sql=new_sql, cur=cur, conn=conn)
recursive_delete(sql=org_sql, cur=cur, conn=conn)
最后,我更改了information_schema
中如何查询引用表的实现,解决了问题。
def recursive_delete(all_sql, cur, conn):
for sql in all_sql[::-1]:
sql_post = sql[sql.index('where'):]
try:
print(sql)
cur.execute(sql)
conn.commit()
except mysql.connector.IntegrityError as e:
err = e.msg
ss = r'`([\w_]+)`'
info = re.findall(ss, err)
db, table, constraint_name, foreign_key = info[0], info[1], info[2], info[3]
sql_reference_table_and_reference_key = 'select REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.KEY_COLUMN_USAGE where TABLE_NAME="{table}" and CONSTRAINT_NAME="{constraint_name}" and COLUMN_NAME="{foreign_key}"'.format(table=table, constraint_name=constraint_name,
foreign_key=foreign_key)
print(sql_reference_table_and_reference_key)
cur.execute(sql_reference_table_and_reference_key)
result = cur.fetchone()
reference_table, reference_key = result[0], result[1]
new_sql = "delete from {db}.{table} where {foreign_key} in (select {reference_key} from {reference_table} {sql_post})".format(db=db, table=table, foreign_key=foreign_key, reference_key=reference_key, reference_table=reference_table, sql_post=sql_post)
sql_strings.append(new_sql)
recursive_delete(all_sql=all_sql, cur=cur, conn=conn)