【问题标题】:Using python to write mysql query to csv, need to show field names使用python写mysql查询到csv,需要显示字段名
【发布时间】:2011-06-04 13:11:19
【问题描述】:

我有以下几点:

import MySQLdb as dbapi
import sys
import csv

dbServer='localhost'
dbPass='supersecretpassword'
dbSchema='dbTest'
dbUser='root'

dbQuery='SELECT * FROM pbTest.Orders;'

db=dbapi.connect(host=dbServer,user=dbUser,passwd=dbPass)
cur=db.cursor()
cur.execute(dbQuery)
result=cur.fetchall()

c = csv.writer(open("temp.csv","wb"))
c.writerow(result)

这会产生乱码。我熟悉使用打印记录 [0] 等。不知道我应该如何设置格式。产生类似于控制台中的查询的东西。我不能从 mysql 服务器做一个简单的 INTO OUTFILE。


更新

已经 8 年了;我仍然偶尔会收到有关此问题的更新或查询。

正如一些 cmets 所述,DBAPI 中的 cursor.description 正是我所寻找的。​​p>

这是 Python 3 中更现代的示例,它使用 pymysql 驱动程序连接到 MariaDB,它将选择所有行并将其提取到一个元组中,将行标题/描述提取到一个列表中。然后我将这两个数据结构合并到一个列表中,即written to a csv file

标题名称是结果列表中的第一个条目;以线性方式将结果写入文件可确保行标题是 CSV 文件中的第一行。

import pymysql
import csv
import sys

db_opts = {
    'user': 'A',
    'password': 'C',
    'host': 'C',
    'database': 'D'
}

db = pymysql.connect(**db_opts)
cur = db.cursor()

sql = 'SELECT * from schema_name.table_name where id=123'
csv_file_path = '/tmp/my_csv_file.csv'

try:
    cur.execute(sql)
    rows = cur.fetchall()
finally:
    db.close()

# Continue only if there are rows returned.
if rows:
    # New empty list called 'result'. This will be written to a file.
    result = list()

    # The row name is the first entry for each entity in the description tuple.
    column_names = list()
    for i in cur.description:
        column_names.append(i[0])

    result.append(column_names)
    for row in rows:
        result.append(row)

    # Write result to file.
    with open(csv_file_path, 'w', newline='') as csvfile:
        csvwriter = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
        for row in result:
            csvwriter.writerow(row)
else:
    sys.exit("No rows found for query: {}".format(sql))

【问题讨论】:

    标签: python mysql csv mariadb pymysql


    【解决方案1】:

    上一个答案会出错。必须先将标头写入文件,然后再添加行。以下对我有用。

    rows = cursor.fetchall()
    headers = [col[0] for col in cursor.description] # get headers
    rows.insert(0, tuple(headers))
    fp = open('/tmp/file.csv', 'w', newline = '') 
    myFile = csv.writer(fp)
    myFile.writerows(rows)
    fp.close()
    

    【讨论】:

    • 为什么要添加标题和行?这将写入标题两次。
    【解决方案2】:
    import pymysql
    import sys
    import csv
    
    connection = pymysql.connect(host='abcde',
    user='admin',
    password='secret',
    db='databaseName',
    port=12345)
    
    dbQuery="SELECT field1, field2, fieldn FROM database.table;"
    cur=connection.cursor()
    cur.execute(dbQuery)
    rows=cur.fetchall()
    column_names = [i[0] for i in cur.description]
    fp = open('DimDevice.csv', 'w')
    myFile = csv.writer(fp, lineterminator = '\n')
    myFile.writerow(column_names)   
    myFile.writerows(rows)
    fp.close()
    

    【讨论】:

      【解决方案3】:

      为遇到此问题的任何人提供列标题名称: (我正在使用Jwhat的方法写入csv)

      result = cur.fetchall()
      
      #Getting Field Header names
      column_names = [i[0] for i in cur.description]
      fp = open('Result_Set.csv' 'w')
      myFile = csv.writer(fp, lineterminator = '\n') #use lineterminator for windows
      myFile.writerow(column_names)
      myFile.writerows(result)
      fp.close()
      

      【讨论】:

        【解决方案4】:

        只需在@jwhat 答案中再添加一件事。

        如果您打算在 Windows 中打开此 csv 文件,则需要处理多余的空行。

        只需将代码更改为以下代码,因为 2.7 中的默认 lineterminator 是 \r\n

        myFile = csv.writer(fp, lineterminator='\n')
        

        【讨论】:

        • 谢谢!我一直打开excel并从那里删除空白行,这总是很痛苦,我从来没有想过要停止它。
        【解决方案5】:

        您可以将所有结果转储到 csv 文件而无需循环:

        rows = cursor.fetchall()
        fp = open('/tmp/file.csv', 'w')
        myFile = csv.writer(fp)
        myFile.writerows(rows)
        fp.close()
        

        【讨论】:

        • 很好的答案。我只需将 'file' 变量更改为 myfile 之类的变量,因为 'file' 是关键字。
        • 这很好用,但无论如何我也可以得到字段名/列名。
        • 谢谢,发现这个很方便。
        • @JakeWagner 在writerows() 之前添加writer.writeheader()
        • 我的 csv 没有正确显示。它不只是直线填充单元格
        【解决方案6】:

        result 是行列表。因此,您需要遍历该列表并写入每一行:

        for row in result:
            c.writerow(row)
        

        【讨论】:

        • 非常感谢,知道如何写出字段名称吗?
        • @teatime - 您可以从result[0].keys(或等效的row.keys)获取字段名。
        • 不幸的是,这个答案并没有完全回答问题的标题(“需要显示字段名称”)。 @mtrw 的评论有帮助,但不适用于给定的代码(元组对象没有属性“键”)。如果游标是字典游标,即使用dbconn.cursor(dictionary=True) 创建,则可能适用。
        • 当使用字典游标时,result[0].keys() 给出一个列名列表。但是,它(通常)与您从result[0] 获得的非字典游标的顺序不同,也与您在 MySQL 客户端中看到的顺序不同。简而言之,这是一团糟。如果列顺序无关紧要,这可能没问题。
        【解决方案7】:

        我知道一点 python,但是在谷歌搜索之后,你应该使用写入多行的 writerows(带有 S),而不是需要单行的 writerow。

        正如我所说,这对我来说有点像在黑暗中刺伤。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-02-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多