【问题标题】:MySQL date range pull using Python : TypeError:unhashable type: 'bytearray'MySQL 日期范围使用 Python 拉取:TypeError:unhashable type: 'bytearray'
【发布时间】:2016-03-29 00:32:13
【问题描述】:

我试图弄清楚如何从一个表中提取数据,该表有一个名为“sent_time”的列并且日期时间介于两个日期时间之间。我终于能够弄清楚如何使用 dateutil 解析器来输入日期范围拉取的两个日期。我现在的问题是我收到了这个错误:

Traceback (most recent call last):
  File "C:\Python34\timerange.py", line 75, in <module>
    worksheet.write(r,0,row[0])
  File "C:\Python34\lib\site-packages\xlsxwriter\worksheet.py", line 64, in cell_wrapper
    return method(self, *args, **kwargs)
  File "C:\Python34\lib\site-packages\xlsxwriter\worksheet.py", line 436, in write
    return self.write_string(row, col, *args)
  File "C:\Python34\lib\site-packages\xlsxwriter\worksheet.py", line 64, in cell_wrapper
    return method(self, *args, **kwargs)
  File "C:\Python34\lib\site-packages\xlsxwriter\worksheet.py", line 470, in write_string
    string_index = self.str_table._get_shared_string_index(string)
  File "C:\Python34\lib\site-packages\xlsxwriter\sharedstrings.py", line 128, in _get_shared_string_index
    if string not in self.string_table:
TypeError: unhashable type: 'bytearray'

让我困惑的是字节数组。你们能告诉我我做错了什么以及如何解决它吗?


我想向您提供我拥有的所有其他文件的所有信息以及我正在拍摄的内容,以查看您是否可以复制并实际运行它只是为了看看它是否不仅仅是我的系统或我拥有的某些配置..

我有一个带有一个表的数据库。我们称它为“table1”。该表按如下所示的列进行细分:

发送时间 |交付时间 |id1_active |id2_active |id3_active |id1_inactive |id2_inactive |id3_inactive |location_active |location_inactive .....`更多

假设这是两个或多个客户相互运送货物。每个客户都有三个 id#。

我创建了一个“config.ini”文件让我的生活更轻松

[mysql]
host = localhost
database = db_name
user = root
password = blahblah

我创建了一个“python_mysql_dbconfig.py”

from configparser import ConfigParser

def read_db_config(filename=’config.ini’, section=’mysql’):
“”” Read database configuration file and return a dictionary object
:param filename: name of the configuration file
:param section: section of database configuration
:return: a dictionary of database parameters
“””
# create parser and read ini configuration file
parser = ConfigParser()
parser.read(filename)

# get section, default to mysql
db = {}
if parser.has_section(section):
items = parser.items(section)
for item in items:
db[item[0]] = item[1]
else:
raise Exception(‘{0} not found in the {1} file’.format(section, filename))

return db

这是我现在正在编写的代码……你能看一下吗?

# Establish a MySQL connection
from mysql.connector import MySQLConnection, Error
from python_mysql_dbconfig import read_db_config
db_config = read_db_config()
conn = MySQLConnection(**db_config)
cursor = conn.cursor(raw=True)

#to export to excel
import xlsxwriter
from xlsxwriter.workbook import Workbook

#to get the csv converter functions
import os
import subprocess
import glob

#to get the datetime functions
import datetime
from datetime import datetime
import dateutil.parser

#creates the path needed for output files
path = 'C:/Python34/output_files/'

#creates the workbook
output_filename = input('output filename:')
workbook = xlsxwriter.Workbook(path + output_filename + '.xlsx')
worksheet = workbook.add_worksheet()

#formatting definitions
bold    = workbook.add_format({'bold': True})
date_format = workbook.add_format({'num_format': 'yyyy-mm-dd hh:mm:ss'})
timeShape =  '%Y-%m-%d %H:%M:%S'

#actual query


query = (
    "SELECT sent_time, delivered_time, OBJ, id1_active, id2_active, id3_active, id1_inactive, id2_inactive, id3_inactive, location_active, location_inactive FROM table1 "
    "WHERE sent_time BETWEEN %s AND %s"
)
userIn = dateutil.parser.parse(input('start date:'))
userEnd = dateutil.parser.parse(input('end date:'))


# Execute sql Query
cursor.execute(query,(userIn, userEnd))
result = cursor.fetchall()


#sets up the header row
worksheet.write('A1','sent_time',bold)
worksheet.write('B1', 'delivered_time',bold)
worksheet.write('C1', 'customer_name',bold)
worksheet.write('D1', 'id1_active',bold)
worksheet.write('E1', 'id2_active',bold)
worksheet.write('F1', 'id3_active',bold)
worksheet.write('G1', 'id1_inactive',bold)
worksheet.write('H1', 'id2_inactive',bold)
worksheet.write('I1', 'id3_inactive',bold)
worksheet.write('J1', 'location_active',bold)
worksheet.write('K1', 'location_inactive',bold)
worksheet.autofilter('A1:K1')  #dropdown menu created for filtering


#print into client to see that you have results
print("     sent_time     ", "        delivered_time     ", "OBJ", "\t   id1_active  ", "   id2_active  ", "    id3_active  ", "\t", " id1_inactive ", " id2_inactive ", "  id3_inactive ", "\tlocation_active", "\tlocation_inactive")
for row in result:
    print(*row, sep='\t')


# Create a For loop to iterate through each row in the XLS file, starting at row 2 to skip the headers
for r, row in enumerate(result, start=1):  #where you want to start printing results inside workbook
    for c, col in enumerate(row):
        worksheet.write_datetime(r,0,row[0], date_format)
        worksheet.write_datetime(r,1, row[1], date_format)
        worksheet.write(r,2, row[2])
        worksheet.write(r,3, row[3])
        worksheet.write(r,4, row[4])
        worksheet.write(r,5, row[5])
        worksheet.write(r,6, row[6])
        worksheet.write(r,7, row[7])
        worksheet.write(r,8, row[8])
        worksheet.write(r,9, row[9])
        worksheet.write(r,10, row[10])




#close out everything and save
cursor.close()
workbook.close()
conn.close()

#print number of rows and bye-bye message
print ("- - - - - - - - - - - - -")
rows = len(result)
print ("I just imported "+ str(rows) + " rows from MySQL!")
print ("")
print ("Good to Go!!!")
print ("")


#CONVERTS JUST CREATED FILE TO CSV

# set path to folder containing xlsx files

out_path ='C:/Python34/csv_files'
os.chdir(path)


# find the file with extension .xlsx
xlsx = glob.glob(output_filename + '.xlsx')

# create output filenames with extension .csv
csvs = [x.replace('.xlsx','.csv') for x in xlsx]

# zip into a list of tuples
in_out = zip(xlsx,csvs)

# loop through each file, calling the in2csv utility from subprocess
for xl,csv in in_out:
   out = open(csv,'w')
   command = 'c:/python34/scripts/in2csv %s\\%s' % (path,xl)
   proc = subprocess.Popen(command,stdout=out)
   proc.wait()
   out.close()

print('XLSX and CSV files named ' + output_filename + ' were created')

【问题讨论】:

  • 这里有太多的代码和不相关的细节。您需要查看这些参数中的类型 - worksheet.write(r,0,row[0])。并找出为什么 db 驱动程序将某些内容从您的表映射到字节数组而不是字符串(如果这是实际发生的情况)
  • 我给出了我所有的代码,看看是否有人想复制我正在做的事情,看看我做错了什么。我知道关闭我的代码的是我使用 dateutil.parser.parse 的 userIn 和 UserEnd 输入。我试图弄清楚如何在 worksheet.write(r,0,row[0]) 处将其转换回字符串
  • 如果你想让别人复制这个问题,你这样做不是转储你所有的代码。 stackoverflow.com/help/mcve 但是你应该首先研究为什么你得到一个字节数组而不是一个字符串。 mysql中的列类型可能与它有关。
  • 谢谢我下次再做。
  • 在“#print into client to see that you have results”之前放一个print(map(type, result[0])),看看它会吐出什么。

标签: python-3.x bytearray mysql-python date-range


【解决方案1】:

您已在 cursor = conn.cursor(raw=True) 中禁用类型转换。删除raw=True,以便驱动程序停止为您提供所有类型的直接字节数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    相关资源
    最近更新 更多