2012-10-05 62 views
0

我想添加一个links属性到每个基于csv文件中的数据的每个couchdb文档。 的链接属性的值是包含链接的文档的CouchDB的_idlinkType添加一个链接的文档ID的数组到python的couchdb文档

当我运行该脚本,我得到一个链接错误(请参阅下面的错误信息) 我不知道类型的字典的数组如果它不存在并创建字典密钥links,并添加链接数据,或者如果它存在,则会附加到links数组。

与链接的文档的一个例子是这样的:

{ 
    _id: p_3, 
    name: 'Smurfette' 
    links: [ 
       {to_id: p_2, linkType: 'knows'}, 
       {to_id: o_56, linkType: 'follows'} 
      ] 
} 

处理CSV文件的Python脚本:

#!/usr/bin/python 
# coding: utf-8 

# Version 1 
# 
# csv fields: ID,fromType,fromID,toType,toID,LinkType,Directional 


import csv, sys, couchdb 


def csv2couchLinks(database, csvfile): 

    # CouchDB Database Connection etc 
    server = couchdb.Server() 
    #assumes that couchdb runs on http://localhost:5984 
    db = server[database] 
    #assumes that db is already created 

    # CSV file 
    data = csv.reader(open(csvfile, "rb")) # Read in the CSV file rb=read/binary 
    csv_links= csv.DictReader(open(csvfile, "rb")) 


    def makeLink(from_id, to_id, linkType): 
     # get doc from db 
     doc = db[from_id] 

     # construct link object 
     link = {'to_id':to_id, 'linkType':linkType} 

     # add link reference to array at key 'links' 
     if doc['links'] in doc: 
      doc['links'].append(link) 
     else: 
      doc['links'] = [link] 

     # update the record in the database 
     db[doc.id] = doc 


    # read each row in csv file 
    for row in csv_links: 

     # get entityTypes as lowercase and entityIDs 
     fromType = row['fromType'].lower() 
     fromID = row['fromID'] 
     toType = row['toType'].lower() 
     toID  = row['toID'] 

     linkType = row['LinkType'] 

     # concatenate 'entity type' and 'id' to make couch '_id' 
     fromIDcouch = fromType[0]+'_'+fromID #eg 'p_2' <= person 2 
     toIDcouch = toType[0]+'_'+toID 

     makeLink(fromIDcouch, toIDcouch, linkType) 
     makeLink(toIDcouch, fromIDcouch, linkType) 


# Run csv2couchLinks() if this is not an imported module 
if __name__ == '__main__': 
    DATABASE = sys.argv[1] 
    CSVFILE = sys.argv[2] 
    csv2couchLinks(DATABASE,CSVFILE) 

错误信息:

$ python LINKS_csv2couchdb_v1.py "qmhonour" "./tablesAsCsv/links.csv" 
Traceback (most recent call last): 
    File "LINKS_csv2couchdb_v1.py", line 65, in <module> 
    csv2couchLinks(DATABASE,CSVFILE) 
    File "LINKS_csv2couchdb_v1.py", line 57, in csv2couchLinks 
    makeLink(fromIDcouch, toIDcouch, linkType) 
    File "LINKS_csv2couchdb_v1.py", line 33, in makeLink 
    if doc['links'] in doc: 
KeyError: 'links' 

回答

2

另一种选择是冷凝if块这样的:

doc.setdefault('links', []).append(link) 

字典的setdefault方法检查,看看是否存在于词典links,如果它不它会创建一个键并将该值设置为空列表(缺省值)。然后它将link附加到该列表。如果links确实存在,则只需将link附加到列表中。

def makeLink(from_id, to_id, linkType): 
    # get doc from db 
    doc = db[from_id] 

    # construct link object 
    link = {'to_id':to_id, 'linkType':linkType} 

    # add link reference to array at key 'links' 
    doc.setdefault('links', []).append(link) 

    # update the record in the database 
    db[doc.id] = doc 
+0

,这很好!并且我注意到可以对多层可能不存在的更深的嵌套结构做到这一点。例如。 'doc.setdefault('links',{}).setdefault(toType,[])。append(link)'给出像'{someKey:someValue,链接:{someType:[link]}}这样的结构''' – johowie

+0

Yep ,你知道它:)这是一个非常有用的功能,肯定会从你的代码中删除一些行。 – RocketDonkey

1

更换:

if doc['links'] in doc: 

有了:

if 'links' in doc: 
+0

这适用于我发布的代码。谢谢 – johowie