【问题标题】:Import single csv file with one data field going to separate table导入单个 csv 文件,其中一个数据字段转到单独的表
【发布时间】:2013-08-22 22:38:52
【问题描述】:

我有一个包含Products 列表的 csv 文件,其中包含以下 4 个字段

Product ID, Name, Alias, UOM

我想将文件导入到有 2 个表的数据库中。第一个是Product 表:

Product ID, Name, UOM

第二个是Product Alias表:

Product ID, Alias

每个Product ID 可能有 0 到多个别名。

有什么方法可以让Alias 列与众不同,因为它在逗号之间有不同的分隔符,例如“;”或句号“。”将给定产品 ID 的 0 到多个别名分开?

因此,在 csv 导入期间,当它获得第三个逗号时,它会将该数据导入到第二个表中,但会导入一条新记录,其中包含重复的产品 ID,因为该逗号字段中有许多别名。

希望我解释得足够好,如果我没有解释清楚,请告诉我。无论正在使用什么代码,我对执行此操作的可能处理更感兴趣,但 python 将是首选路线。

示例数据

ProductID, Name,    Alias, UOM
122,       Widget1, W1;    Wid1;Wt1, Each
123,       Widget2, ,      Each
124,       Widget3, W3;    Wt3, Each

【问题讨论】:

  • 附带说明,使用默认参数时,csv.readerDictReader 将保留这些字段的前导空格 - 例如,第一行中的名称将是 " Widget1",而不是 @ 987654333@。通常skipinitialspace=True 可以解决这个问题……但如果您正在生成 CSV,最好以更类似于 Excel 的格式生成它,而不使用这些空格和/或使用引号,除非 CSV 文件是人类可读的很重要。

标签: python csv import


【解决方案1】:

这很容易做到。

首先,您像往常一样使用csv 来获取所有列。其中一列本身就是一个以分号分隔的值列表。

如果您不需要担心引用等问题,您可以使用split。例如:

with open('foo.csv') as f:
    for row in csv.DictReader(f):
        cursor.execute('''INSERT INTO Product (ProductID, Name, UOM) 
                          VALUES (:ProductID, :Name, :UOM)''', row)
        for alias in row['Alias'].split(';'):
            cursor.execute('''INSERT INTO ProductAlias (Name, Alias) 
                              VALUES (?, ?)''', row['Name'], alias)

如果您可以在别名中包含空格,您将需要两种引用或转义,以及两种分隔符。像这样:

123,"Widget 1","Widget1;W1;Wid1;Wt1;'W 1'",Each

并且您想使用另一个csv.reader 来解析它。当然csv 旨在将一系列行解析为一系列行,而不是将单行解析为单行,但这很容易处理,只需将单行包装在列表中,然后从中提取单行结果。例如,而不是这个:

row['Alias'].split(';')

……这样做:

next(csv.reader([row['Alias']], delimiter=";", quotechar="'"))

(尽管一旦变得如此复杂,您可能希望将表达式拆分为多个步骤。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 2018-03-31
    • 2011-07-16
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多