使用Python函数为多个MySQL表添加外键时出现SQL 1064错误如何解决
错误触发原因
- SQL拼接缺少空格:多段f-string拼接时相邻语句之间没有预留空格,会直接拼接成非法语法,比如会生成
ALTER TABLE Bien_ImmoADD COLUMN fk_Id_Lot这类完全不符合MySQL语法规范的语句。 - 外键约束语法错误:
ADD CONSTRAINT后多写了多余的ADD关键字,正确的约束定义语法是ADD CONSTRAINT 约束名 FOREIGN KEY (列名) 关联父表,不需要额外加ADD。 - 新增列缺少类型定义:
ADD COLUMN语句只写了列名,没有指定列的数据类型,该类型必须和父表关联列的类型完全一致,否则即使语法修复也会报错。
修复方案
调整create_fk函数的SQL拼接逻辑,修正语法错误,新增外键列类型参数适配不同场景,修改后的可运行代码如下:
from sqlalchemy import create_engine def create_fk(child_table, fk_name, parent_table, parent_col, fk_col_type="INT"): url = "mysql+pymysql://{user}:{password}@localhost/{db}" engine = create_engine(url.format(user='root', password='******', db='data_immo')) # 三引号编写SQL避免空格拼接问题,修正语法错误 alter_sql = f""" ALTER TABLE {child_table} ADD COLUMN {fk_name} {fk_col_type}, ADD CONSTRAINT {fk_name} FOREIGN KEY ({fk_name}) REFERENCES {parent_table}({parent_col}) ON DELETE CASCADE """ engine.execute(alter_sql) d_fk = {'Bien_Immo': ['fk_Id_Lot', 'Lot', 'Id']} for key in d_fk.keys(): if isinstance(d_fk[key][0], list): for i in range(len(d_fk[key])): n2, n3, n4 = d_fk[key][i][0], d_fk[key][i][1], d_fk[key][i][2] # 可根据父表关联列实际类型修改fk_col_type参数 create_fk(key, n2, n3, n4, fk_col_type="INT UNSIGNED NOT NULL") else: n2, n3, n4 = d_fk[key][0], d_fk[key][1], d_fk[key][2] create_fk(key, n2, n3, n4, fk_col_type="INT UNSIGNED NOT NULL")
注意事项
- 外键列的类型必须和父表关联列完全一致,包括是否无符号、是否为空等属性,否则会触发类型不匹配错误。
- 执行前确保父表已经存在,且关联列是父表的主键或者唯一索引,否则外键创建会失败。
- 如果子表已经有数据,要确保新增的外键列的值符合父表关联列的取值范围,或设置列允许为空,否则会触发数据校验错误。
内容的提问来源于stack exchange,提问作者de Beyssac Olivier
相关产品推荐
相关产品推荐

