我试图使用sqlalchemy (版本1.0.11)在一个表上执行一个多插入,该表的列名中包含百分比符号。行可以一次插入一个,没有问题,但是当使用con.execute()执行多插入时,会引发OperationalError异常。
下面的代码再现了这个问题。创建了两个表,一个在列中包含百分比名称,另一个没有。
from sqlalchemy import *
USER = 'root'
PASSWORD = ''
HOST = '127.0.0.1'
DBNAME = 'test'
connect_str = "mysql://{USER}:{PASSWORD}@{HOST}/{DBNAME}".format(
USER = USER,
PASSWORD = PASSWORD,
HOST = HOST,
DBNAME = DBNAME
)
engine = create_engine(connect_str, echo = False)
metadata = MetaData()
table_with_percent = Table('table_with_percent', metadata,
Column('A%', Integer),
Column('B%', Integer)
)
table_no_percent = Table('table_no_percent', metadata,
Column('A', Integer),
Column('B', Integer)
)
metadata.create_all(engine, checkfirst = True)
#####################################
# Create rows to be inserted
rows = [(1,2), (3,4), (5,6)]
table_with_percent_rows = [dict(zip(table_with_percent.c.keys(), row)) for row in rows]
table_no_percent_rows = [dict(zip(table_no_percent.c.keys(), row)) for row in rows]试着插入
con = engine.connect()失败! Mutli在表上插入列名中的百分比符号。
OperationalError: (_mysql_exceptions.OperationalError) (1054, "Unknown column 'A%%' in 'field list'") [SQL: u'INSERT INTO table_with_percent (`A%%`, `B%%`) VALUES (%s, %s)'] [parameters: ((1, 2), (3, 4), (5, 6))]
con.execute(table_with_percent.insert(), table_with_percent_rows)但行可以一个接一个地插入:
for row in table_with_percent_rows:
con.execute(table_with_percent.insert(), row)这是可行的!多插入表中没有百分比列
con.execute(table_no_percent.insert(), table_no_percent_rows)
con.close()更新:i用sqlalchemy问题跟踪器打开了这问题。
发布于 2015-12-29 02:49:44
在列/表名中使用花哨字符(除A-Z、0-9和_以外的任何字符)警告是一种保证的方法。
TL;博士,这似乎是SQLAlchemy中的一个bug。它不正确地转义名为%的列。您可以转到问题跟踪器并报告一个bug (如果还没有报告)。
您希望在do_execute()方法sqlalchemy.engine.default.DefaultDialect中放置一个断点。它是将查询和参数从SA传递给数据库驱动程序的地方。在您的示例中,SQL如下所示:
INSERT INTO table_with_percent (`A%%`, `B%%`) VALUES (%s, %s)是的,SQLAlchemy在列名中添加了第二个%。这显然会使列无效。你最好问问问题追踪器为什么会发生这种情况。
由于幸运的巧合,单行插入就能工作。"%s" % ("value",)语法用于将参数格式化为查询。在格式字符串中,%%是转义%字符的方法,因此格式化查询后返回到正确的表单:
INSERT INTO table_with_percent (`A%`, `B%`) VALUES (1, 2)在插入多行的情况下,幸运的巧合不会发生,因为对params的格式化是不同的。最后得到以下查询:
INSERT INTO table_with_percent (`A%%`, `B%%`) VALUES (1, 2), (3, 4), (5, 6)这显然是失败的。
PS您可以使用以下语法来使其工作:
con.execute(table_with_percent.insert().values(table_with_percent_rows))https://stackoverflow.com/questions/34464842
复制相似问题