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)