我正在尝试使用 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]
Run Code Online (Sandbox Code Playgroud)
con = engine.connect()
Run Code Online (Sandbox Code Playgroud)
这失败了!在列名称中使用百分比符号在表上插入多处。
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)
Run Code Online (Sandbox Code Playgroud)
但是可以一一插入行:
for row in table_with_percent_rows:
con.execute(table_with_percent.insert(), row)
Run Code Online (Sandbox Code Playgroud)
这有效!在表上多次插入,列中没有百分比
con.execute(table_no_percent.insert(), table_no_percent_rows)
con.close()
Run Code Online (Sandbox Code Playgroud)
更新:我用 sqlalchemy 问题跟踪器打开了这个问题。
警告在列/表名称中使用花哨的字符(除A-Z,0-9和之外的任何_字符)是搬起石头砸自己脚的保证方法之一。
TL;DR这似乎是 SQLAlchemy 中的一个错误。它错误地转义了%名称为 in 的列。您可以转到问题跟踪器并报告错误(如果尚未报告)。
do_execute()您想在 的方法中放置一个断点sqlalchemy.engine.default.DefaultDialect。在这里,您的查询和参数从 SA 传递到数据库驱动程序。在你的例子中,SQL 看起来像这样:
INSERT INTO table_with_percent (`A%%`, `B%%`) VALUES (%s, %s)
Run Code Online (Sandbox Code Playgroud)
是的,SQLAlchemy%在列名称中添加了第二个。这显然会使列无效。您最好在问题跟踪器上询问为什么会发生这种情况。
由于幸运的巧合,插入单行就可以了。"%s" % ("value",)语法用于将参数格式化为查询。并且格式字符串中%%是转义字符的方式%,所以格式化后查询返回到正确的形式:
INSERT INTO table_with_percent (`A%`, `B%`) VALUES (1, 2)
Run Code Online (Sandbox Code Playgroud)
如果插入多行,则不会发生幸运的巧合,因为参数的格式设置不同。您最终会得到以下查询:
INSERT INTO table_with_percent (`A%%`, `B%%`) VALUES (1, 2), (3, 4), (5, 6)
Run Code Online (Sandbox Code Playgroud)
这显然失败了。
PS 您可以使用以下语法来使其工作:
con.execute(table_with_percent.insert().values(table_with_percent_rows))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1440 次 |
| 最近记录: |