MySqlDb在插入忽略语句时抛出操作数应包含1列的错误

5 投票
2 回答
10871 浏览
提问于 2025-04-17 20:32

在查看Stack Exchange提供的一些websocket方法时,我想把一些数据点保存到MySQL数据库里。但是,当我尝试运行一个executemany命令时,出现了以下错误:

_mysql_exceptions.OperationalError: (1241, '操作数应该包含1列')

我在Stack Overflow上查找这个错误时,发现很多例子都提到要去掉SELECT语句中的括号。但我并没有使用SELECT,我是在尝试INSERT

我的代码的一个简短示例看起来是这样的:

import MySQLdb as mdb
db = mdb.connect(host='localhost',user='myuser',db='qs',passwd='mypass',use_unicode=True,charset='utf8')
cur = db.cursor()
db_qry = """INSERT IGNORE INTO questions (id, site_base, title, body_sum, tags, last_act_dt, url, owner_url, owner, api_site) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""


parms = [(u'mathematica.stackexchange.com', 
43248, 
u'How to plot “Normalized distance” in this problem', 
u"Problem: there are two particles whose equationsof motion both satisfy -n Abs[x[t]]^n/x[t] == x''[t]. But their initial conditions are different: one is x'[0] == 0, x[0] == 2;another is x'[0] == 0, ...", 
[u'plotting', u'equation-solving', u'differential-equations', u'numerical-integration', u'notebooks'],
1393801095,
u'http://mathematica.stackexchange.com/questions/43248/how-to-plot-normalized-distance-in-this-problem',
u'http://mathematica.stackexchange.com/users/12706/lawerance', u'Lawerance', u'mathematica')]

cur.executemany(db_qry, parms)
cur.commit()

我是不是错误地使用了executemany?或者在传递给executemany之前,我的parms列表中缺少了什么需要清理的内容?

2 个回答

1

我在尝试通过 pandas.DataFrame.to_sql 将一个包含列表的列保存到 MySQL 数据库时遇到了问题,这个方法可以自动化一些操作。通常,我不使用 join,而是把列表转换成编码后的字符串,使用 json.dumps()json 这个包也很方便,可以用 json.loads() 把数据重新加载回原来的格式。

在原始示例中,我会把 parms 转换成一个数据框。

parms = pd.DataFrame(parms)
parms
                               0      1  \
0  mathematica.stackexchange.com  43248

                                                   2  \
0  How to plot “Normalized distance” ...

                                                   3  \
0  Problem: there are two particles whose equatio...

                                                   4           5  \
0  [plotting, equation-solving, differential-equa...  1393801095

                                                   6  \
0  http://mathematica.stackexchange.com/questions...

                                                   7          8            9
0  http://mathematica.stackexchange.com/users/127...  Lawerance  mathematica

然后把包含列表的那一列转换成 json 字符串:

parms[4] = parms[4].apply(json.dumps)
parms

0  mathematica.stackexchange.com  43248

                                                   2  \
0  How to plot “Normalized distance” ...

                                                   3  \
0  Problem: there are two particles whose equatio...

                                                   4           5  \
0  ["plotting", "equation-solving", "differential...  1393801095

                                                   6  \
0  http://mathematica.stackexchange.com/questions...

                                                   7          8            9
0  http://mathematica.stackexchange.com/users/127...  Lawerance  mathematica

接着,启动一个 MySQL 连接(使用上面提供的详细信息):

import sqlalchemy
call = 'mysql+mysqldb://myuser:mypass@localhost:3306/qs' 
engine = sqlalchemy.create_engine(call)

最后,使用 pandas 内置的函数把数据存入数据库:

parms.to_sql('questions', engine, if_exists='append', chunksize=5000)
5

问题出在传入到 tags 这一列的数据上。它试图传递一个列表,而不是一个字符串。

在我最初提问的例子中,我使用了这段代码把它转换成了字符串。

','.join([u'plotting', u'equation-solving', u'differential-equations', u'numerical-integration', u'notebooks'])

还要提到的是,我搞错了提交的代码行。应该是 db.commit(),而不是 cur.commit()

撰写回答