【问题标题】:Mapping rows ids with external csv file?使用外部 csv 文件映射行 ID?
【发布时间】:2014-05-08 13:05:06
【问题描述】:

我有一个包含地址信息的 csv 文件:zipcitystatecountrystreethouse_no(最后一个是门牌号)。这是通过 OpenERP 导入界面导入的。因此,您可以通过提供以下三种之一来导入相关数据 - namedatabase idexternal 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 或州名来区分相同的名称。

以及地址 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 表中并返回 ids 列表。

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

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

它应该向我输出这个:

1
2
3
1

有人可以建议我如何得到这样的结果吗?

【问题讨论】:

  • 你的问题很难理解!您真正想要做什么 - 更正数据库中的所有条目?或者改进您的 CSV 导入例程以供将来添加?您谈论“csv 文件中的匹配条件”但 CSV 文件不表达条件。在你最后的例子中,你的数字列表从 1,2,2,1 到 1,2,3,1 没有明显的原因。
  • 很抱歉提出这样的问题。想不出怎么更容易表达。我想要的是获取我想与地址 csv 关联的城市的 ID(在地址表中导入时)。现在我有了名字,但正如我所写的,可以有相同的名字,所以需要 id。对于 id,这是两个不同的表 id。第一个1, 2, 2, 1state 表行ID,第二个(1, 2, 3, 1 您可以在city 表示例中看到这些城市与这些ID 匹配)是city 表行ID。
  • ...继续。所以我输入city 名称和state_id 并返回city id,它与这两个条件匹配。

标签: python sql postgresql csv openerp


【解决方案1】:

我可以通过编写这个脚本来解决这个问题:

# -*- 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()

【讨论】:

    猜你喜欢
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多