我尝试使用以下SQL语法填充MySQL数据库中的表,其中每行的值来自文本文件:
INSERT INTO Table SET
fieldname1 = "value1",
fieldname2 = "value2",
fieldname3 = "value3";
我使用嵌套的for
循环来打印一个字符串(名为SQL3
),该字符串对文本文件的每一行使用相同的字段名称,试图以正确的方式处理语法。好像我已经接近但它仍然向我抛出SQL语法错误,我似乎对可能发生的事情视而不见。在第一次尝试通过Python连接到数据库时,可能还有更多隐藏在下面的问题。
希望有人可以帮助找到问题。是否缺少一些重要信息?
这是代码:
import MySQLdb
fieldNames = """Org_rowNr_countsheet
Orig_row_10604
pt3
pt3_ensembl_id
status
pt2_meth
pt3_meth
pt2_kegg_id
pt2_uniprotID
pt3_kegg_hit
pt3_uniprot
pt2_contig
pt2_start
pt2_stop
pt2_strand
pt3_contig
pt3_start
pt3_stop
pt3_strand
"""
fieldnames = fieldnames.strip().split("\n")
myconnection = MySQLdb.connect(host = "localhost", user = 'root', passwd = "mock", db="pt3_annot")
mycursor = myconnection.cursor()
infilename = "/home/oaklander114/winshare/mysql_pt3/pt3_annot_ids_reduced.csv"
infile = open(infilename, 'r')
linenumber = 0
for line in infile:
if linenumber > 0:
line = line.strip("\n\r")
fields = line.split(',')
print 'INSERT INTO ids SET '
for i, fieldname in enumerate(fieldnames):
query = []
if i < 18:
SQL1 = """
%s = '%s',
""" % (fieldname, fields[i])
query.append(SQL1)
else:
SQL2 = """
%s = '%s';
""" % (FieldName, Fields[i])
query.append(SQL2)
SQL3 = " ".join(query)
print SQL3
mycursor.execute(SQL3)
linenumber += 1
infile.close()
mycursor.close()
myconnection.commit()
myconnection.close()
这是错误消息:
ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Org_rowNr_countsheet = '10578',' at line 1")
我认为在错误点显示语法的打印会很有用,因为脚本似乎正在生成它(看起来对我来说):
INSERT INTO ids SET
Org_rowNr_countsheet = '10579',
Orig_row_10604 = '',
pt3 = '300002',
等...但错误与第一行有关。这是一个更详细的错误报告:
%run /home/oaklander114/winshare/mysql_pt3/insert_rows_ids.py
INSERT INTO ids SET
Org_rowNr_countsheet='10578',
---------------------------------------------------------------------------
ProgrammingError Traceback (most recent call last)
/home/oaklander114/Canopy/appdata/canopy-1.4.1.1975.rh5-x86_64/lib/python2.7/site- packages/IPython/utils/py3compat.pyc in execfile(fname, *where)
202 else:
203 filename = fname
--> 204 __builtin__.execfile(filename, *where)
/home/oaklander114/winshare/mysql_pt3/insert_rows_ids.py in <module>()
52 SQL3 = " ".join(query)
53 print SQL3
---> 54 MyCursor.execute(SQL3)
55
56 LineNumber += 1
/home/oaklander114/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/MySQL_python-1.2.5- py2.7-linux-x86_64.egg/MySQLdb/cursors.pyc in execute(self, query, args)
203 del tb
204 self.messages.append((exc, value))
--> 205 self.errorhandler(self, exc, value)
206 self._executed = query
207 if not self._defer_warnings: self._warning_check()
/home/oaklander114/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/MySQL_python-1.2.5-py2.7-linux-x86_64.egg/MySQLdb/connections.pyc in defaulterrorhandler(***failed resolving arguments***)
34 del cursor
35 del connection
---> 36 raise errorclass, errorvalue
37
38 re_numeric_part = re.compile(r"^(\d+)")
ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Org_rowNr_countsheet='10578',' at line 1")
这些是ids
表的列:
mysql> SHOW COLUMNS FROM ids;
+----------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+--------------+------+-----+---------+-------+
| Org_rowNr_countsheet | varchar(255) | NO | PRI | NULL | |
| Org_row_10604 | varchar(255) | YES | | NULL | |
| pt3 | varchar(255) | YES | | NULL | |
| pt3_ensembl_id | varchar(255) | YES | | NULL | |
| status | varchar(255) | YES | | NULL | |
| pt2_meth | varchar(255) | YES | | NULL | |
| pt3_meth | varchar(255) | YES | | NULL | |
| pt2_kegg_id | varchar(255) | YES | | NULL | |
| pt2_uniprotID | varchar(255) | YES | | NULL | |
| pt3_kegg_hit | varchar(255) | YES | | NULL | |
| pt3_uniprot | varchar(255) | YES | | NULL | |
| pt2_contig | varchar(255) | YES | | NULL | |
| pt2_start | varchar(255) | YES | | NULL | |
| pt2_stop | varchar(255) | YES | | NULL | |
| pt2_strand | varchar(255) | YES | | NULL | |
| pt3_contig | varchar(255) | YES | | NULL | |
| pt3_start | varchar(255) | YES | | NULL | |
| pt3_stop | varchar(255) | YES | | NULL | |
| pt3_strand | varchar(255) | YES | | NULL | |
+----------------------+--------------+------+-----+---------+-------+
19 rows in set (0.00 sec)
答案 0 :(得分:1)
您的代码存在许多问题,包括功能问题和风格问题。对于样式问题,我建议您阅读PEP 8 -- Style Guide for Python Code。具体来说,为包,模块和类保留CamelCase将在StackOverflow上产生更合适的语法高亮。
您在评论中说,您在FieldNames
字符串中发现了拼写错误,但INSERT
语句在您切换到VALUES
语法之前仍然无声地失败。我没有看到INSERT
语法变体与SET
经常使用,但它是正确的,它确实可以使用MySQL-Python工作:
>>> curs.execute('create temporary table tbl (col1 varchar(10), col2 varchar(10))')
0L
>>> statement = r"""
... INSERT INTO tbl SET
... col1 = "value1",
... col2 = "value2";
... """
>>> curs.execute(statement)
1L
>>> curs.execute("select * from tbl")
1L
>>> curs.fetchall()
(('value1', 'value2'),)
所以问题出在其他地方,无论是代码还是期望。除非你清楚地描述这个新问题(并且很可能会涉及重写你的大部分问题),否则我无法确切地说出出了什么问题。但是,我可以指出你的方法存在的一些问题;解决这些问题可能会引导您找到解决方案。
当你应该编写parameterized queries时,你会浪费大量的空间从混乱的字符串构建查询。忘记从字符串到列表的所有来回,并找出你需要逗号或分号的时间;只需使用%s
作为每个值的占位符来编写查询,并将这些值作为execute
方法as shown in the User's Guide的第二个参数提供。
自己解析csv文件而不是简单地使用a standard library module for parsing csv files也是一种浪费,如果familiarize yourself with the with
statement用于文件对象(除其他外),您将编写更好的代码。这是一种不那么容易出错的方式来做你想做的事情:
import csv
import MySQLdb
INSERT_STATEMENT = """
INSERT INTO ids
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s);
"""
INPUT_PATH = '/home/oaklander114/winshare/mysql_pt3/pt3_annot_ids_reduced.csv'
connection = MySQLdb.connect(host='localhost', user='root', passwd='mock',
db='pt3_annot')
with open(INPUT_PATH, 'r') as input_file, connection as cursor:
reader = csv.reader(input_file)
next(reader, None) # skip the header row
for row in reader:
cursor.execute(INSERT_STATEMENT, row)
connection.close()
关于功能的说明:
with
关键字和csv
模块是必不可少的。解析csv文件是一种基本任务,您将被要求在求职面试中展示,在那里您不会花费时间和编写一百行代码。next(reader, None)
没有知道那里有一个标题行;我这样做,从阅读你的代码。如果您将此确切代码与没有标题的文件一起使用,那么它就会出错。with
关键字以这种方式创建MySQLdb游标,会在with
块的末尾自动提交事务。如果您想要执行单独的事务,请在单独的with
块中执行。INSERT_STATEMENT
的列名列为ids
和VALUES
之间的元组。我把它们留在了答案中以节省空间,但这确实使SQL语句和输入文件中隐含了列的顺序。如果要重用此代码,则可能更安全地使列列表显式化。关于风格的说明:
'INSERT INTO ids VALUES ({});'.format(','.join(['%s'] * 19)
)。请注意,此方法依然依赖于游标的execute
方法来正确处理要插入的值,这非常重要。答案 1 :(得分:-1)
2件事。我会将if块从你的循环中取出并确保预先安装正确的SQL。
SQL3 = 'UPDATE table SET ' + " ".join(query) + ';' #don't forget WHERE clause as well...
或者如果你要插入......有效的INSERT语句
您在文件中遇到空行吗?也许试试......
而不是这个(在你的问题中没有正确格式化)
for line in InFile:
if LineNumber > 0:
line = line.strip("\n\r")
#print line
Fields = line.split(',')
试试这个:
for line in InFile:
line = line.strip("\n\r")
if LineNumber > 0 and line != '':
#print line
Fields = line.split(',')
#....rest of your code...