我有一个Python字典,我试图插入到mysql。问题是字典的一个键超过64个字符(mysql中列的最大长度)。所以我需要将所有的字典键截断为64个字符。
下面的代码在所有方面都可以工作,除了一个大于64个字符的键= location_of_building_on_the_lot_if_garage_change_type_code_to_bgd_
data = {'x_coordinate': '1158020.73068669',
'any_people_using_property_homeless_childen_gangs_': True,
'police_district': '8',
'location_of_building_on_the_lot_if_garage_change_type_code_to_bgd_': 'Front',
'service_request_number': '14-00630589',
'address_street_suffix': 'AVE',
'y_coordinate': '1866585.99638448',
'date_service_request_was_received': '2014-05-01T00:00:00',
'address_street_number': '5719',
'longitude': '-87.69612590561026',
'latitude': '41.78965826126179',
'address_street_name': 'FRANCISCO',
'address_street_direction': 'S',
'location': {'latitude': '41.78965826126179', 'needs_recoding': False, 'longitude': '-87.69612590561026'},
'service_request_type': 'Vacant/Abandoned Building',
'community_area': '63',
'is_the_building_currently_vacant_or_occupied_': 'Vacant',
'ward': '16',
'is_building_open_or_boarded_': 'Open',
'is_the_building_vacant_due_to_fire_': True,
'zip_code': '60629'}
placeholders = ', '.join(['%s'] * len(data))
columns = ', '.join(data.keys())
sql = "INSERT INTO vacant_buildings (%s) VALUES (%s)" % (columns, placeholders)
I tried to change:
columns = ', '.join(data.keys())
columns = ', '.join(data[:64].keys())
TypeError: unhashable type
想法吗?
您想截断键(=字符串),而不是数据(它是一个字典,在"字符"的意义上没有"长度"):
columns = ', '.join(d[:64] for d in data.keys())
Pavel的回答很好,但如果您担心由于截断而导致的名称空间冲突
例如,location_of_building_on_the_lot_if_garage_change_type_code_to_bgd_
和location_of_building_on_the_lot_if_garage_change_type_code_to_bgd_hahaha
将是不同的键,直到截断它们,此时它们是相同的键。
keys = []
for k in data.keys():
newKey = k[:64]
count = 1
while newKey in keys:
alteration = str(count)
newKey = newKey[:-len(alteration)] + alteration
count += 1
keys.append(newKey)
columns = ', '.join(keys)
虽然.join()
可以解决这个问题,但它比这样做要慢得多:
columns = ''
for key in data.keys():
columns += key[:64] +', '
sql = "INSERT INTO vacant_buildings (%s) VALUES (%s)" % (columns[:-2], placeholders)
这是因为'.join() '将在你已经迭代过的列表上执行迭代操作,如果你处理的是大量数据,手动操作将会快得多。
还需要注意的是,x[:-2]
适用于小的插入,但是如果您将VALUES
捆绑在一起形成一个单执行字符串,像这样:
INSERT INTO table VALUES (1, 2, 3), (2,2,3), (3,2,3) ...
执行data[:-2]
运算符将变得非常慢,其中一个计数器检查您是否在列表中的最后一项上,从而在最后跳过+', '
。
如果您也要删除值,请在一个for循环中执行此操作,而不是两个:
for key, value in data.items():
columns += key[:64] +', '
为了兼容未来的Python版本,也可以切换到.format()
而不是'something (%s) something else'
,因为这已经过时了。
>>> a = [1, 2, 'test']
>>> '{} is {} with {}'.format(*a)
'1 is 2 with test'
<标题> TL;博士:手动构建字符串,而不是使用导致相同结果的多个迭代函数。使用.format()
!!