首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sqlalchemy多次插入失败,列名中的百分比符号(%)

问Sqlalchemy多次插入失败,列名中的百分比符号(%)
EN

Stack Overflow用户
提问于 2015-12-25 17:16:32
回答 1查看 1.9K关注 0票数 6

我试图使用sqlalchemy (版本1.0.11)在一个表上执行一个多插入,该表的列名中包含百分比符号。行可以一次插入一个,没有问题,但是当使用con.execute()执行多插入时,会引发OperationalError异常。

下面的代码再现了这个问题。创建了两个表,一个在列中包含百分比名称,另一个没有。

  1. 表中包含%的列名的多插入失败。
  2. 在表中一个接一个地插入行,列名中的%起作用。
  3. 在表上插入列名中没有%的多个插入是有效的。
代码语言:javascript
复制
    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]

试着插入

代码语言:javascript
复制
con = engine.connect()

失败! Mutli在表上插入列名中的百分比符号。

代码语言:javascript
复制
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)

但行可以一个接一个地插入:

代码语言:javascript
复制
for row in table_with_percent_rows:
    con.execute(table_with_percent.insert(), row)

这是可行的!多插入表中没有百分比列

代码语言:javascript
复制
con.execute(table_no_percent.insert(), table_no_percent_rows)
con.close()

更新:i用sqlalchemy问题跟踪器打开了这问题。

EN

回答 1

Stack Overflow用户

发布于 2015-12-29 02:49:44

在列/表名中使用花哨字符(除A-Z、0-9和_以外的任何字符)警告是一种保证的方法。

TL;博士,这似乎是SQLAlchemy中的一个bug。它不正确地转义名为%的列。您可以转到问题跟踪器并报告一个bug (如果还没有报告)。

您希望在do_execute()方法sqlalchemy.engine.default.DefaultDialect中放置一个断点。它是将查询和参数从SA传递给数据库驱动程序的地方。在您的示例中,SQL如下所示:

代码语言:javascript
复制
INSERT INTO table_with_percent (`A%%`, `B%%`) VALUES (%s, %s)

是的,SQLAlchemy在列名中添加了第二个%。这显然会使列无效。你最好问问问题追踪器为什么会发生这种情况。

由于幸运的巧合,单行插入就能工作。"%s" % ("value",)语法用于将参数格式化为查询。在格式字符串中,%%是转义%字符的方法,因此格式化查询后返回到正确的表单:

代码语言:javascript
复制
INSERT INTO table_with_percent (`A%`, `B%`) VALUES (1, 2)

在插入多行的情况下,幸运的巧合不会发生,因为对params的格式化是不同的。最后得到以下查询:

代码语言:javascript
复制
INSERT INTO table_with_percent (`A%%`, `B%%`) VALUES (1, 2), (3, 4), (5, 6)

这显然是失败的。

PS您可以使用以下语法来使其工作:

代码语言:javascript
复制
con.execute(table_with_percent.insert().values(table_with_percent_rows))
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34464842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档