我有一个包含地址信息的csv文件:zip
,city
,state
,country
,street
,house_no
(最后一个)一个是门牌号码)。这是通过OpenERP导入界面导入的。因此,您可以通过提供三个中的一个来导入相关数据 - name
,database id
或external id
。最简单的是提供name
。
例如,对于城市,我不需要专门提供它的ID(并且从street
更改为street_id
然后更改该列ID),但只是真实的名称如Some city
。如果city
表中存在此类城市名称,则会导入所有内容而不会出现问题。
但是当有多个同名城市时会出现问题。然后,为了解决名称冲突,我需要专门提供那些城市ID。但问题是,有这么多的地址几乎不可能只是查看并手动将名称更改为ID。
所以我想知道是否有可能编写一些脚本或将该csv文件传递给postgresql(或使用ORM的OpenERP)作为条件,因此它会返回与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
因为你可以看到,如果要转到state
表,可以通过id或state_id或州名来区分相同的名称。
并且有一个adddresses 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
有人可以建议我如何获得这样的结果吗?
答案 0 :(得分: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()