如何将行ID映射到外部CSV文件?

0 投票
1 回答
928 浏览
提问于 2025-04-18 05:49

我有一个包含地址信息的csv文件,里面有:zip(邮政编码)、city(城市)、state(州)、country(国家)、street(街道)和house_no(门牌号)。这些信息是通过OpenERP的导入界面导入的。你可以通过提供三种方式中的一种来导入相关数据:name(名称)、database id(数据库ID)或external id(外部ID)。最简单的方式是提供name

举个例子,对于城市,我不需要特别提供它的ID(也不需要把列名从street改成street_id),只需要提供它的真实名称,比如Some city。如果这个城市名称在city表中存在,那么所有数据就会顺利导入。

但当有多个城市同名时,就会出现问题。这时我需要特别提供这些城市的ID来解决名称冲突。不过问题是,地址数量太多,几乎不可能逐个查看并手动更改名称为ID。

所以我在想,是否可以写个脚本,或者把这个csv文件传给PostgreSQL(或者通过OpenERP使用ORM),作为条件返回与csv文件条件匹配的ID列表。

在我的数据库中,street表和city表已经导入了所有需要的街道和城市。

city表的结构是这样的(附带示例数据):

id| name| state_id|
1 | City1| 1
2 | City1| 2
3 | City2| 2|

state表的示例:

id| name|
1 | State1
2 | State2

所以你可以看到,相同的名称可以通过它们的ID、州ID或州名来区分,如果你去state表查看的话。

还有一个地址的csv文件示例(数据库中也有一个表来导入这些信息):

|zip| city | state_id| country | street| house_no
123 | City1| 1       | Country1| Street1| 25a
124 | City1| 2       | Country1| Street2| 34 
125 | City2| 2       

如果我通过OpenERP界面验证这样的csv文件,我会收到警告,提示有两个城市同名。如果我继续操作,系统会选择第一个导入到数据库中的城市,这样一些地址就会被错误地分配到不正确的州(要记住,城市这一列也用于各种村庄等,所以不同州可能会有相同的名称)。

因此,我需要将城市名称更改为它们的ID,但正如我所说的,数据行数有成千上万,手动操作几乎是不可能的,而且会花费很多时间。

最后,我需要的是以某种方式将所有地址csv文件中的信息传入数据库,特别是传入city表,并获取ID列表的返回结果。

例如,如果我输入(作为city表的条件):

name | state_id|
City1| 1
City1| 2
City2| 2
City1| 1

它应该输出给我这个:

1
2
3
1

有没有人能建议我如何得到这样的结果?

1 个回答

0

我通过写这个脚本解决了这个问题:

# -*- encoding: utf-8 -*-
#!/usr/bin/python

import psycopg2
import csv
#Connect to database
conn = psycopg2.connect(database="db_name",
    user="user", password="password", host="127.0.0.1", port="5432")    
cur = conn.cursor()  
#Get all cities ids and names with specific state  
cur.execute("SELECT id, name from res_country_state_city WHERE state_id = 53")
rows = cur.fetchall()
rows_dict = {}
#Generate dict from data provided
for row in rows:
    rows_dict[row[1]] = row[0]
#Check which name from cities-names.csv match with name in database 
#(match returns that cities id
with open('cities-names.csv') as csvfile:
    with open('cities-ids.csv', 'wb') as csvfile2:
        reader = csv.reader(csvfile)
        writer = csv.writer(csvfile2)
        #create ids csv file and write ids that were matched
        for row in reader:
            if rows_dict.get(row[0]):
                writer.writerow([rows_dict.get(row[0])])    

conn.close()

撰写回答