Importing LDIFs with Python-LDAP

Peter van Rensburg peter at systemsfusion.com
Sat Feb 2 21:59:42 CET 2002


Uhm okay. My bad. 

The "dn: blabla" line is not preffered at the top of the ldif. Seems
like specifying the dn to ldap.add_s is enough. Duh.

Somewhere between Python-LDAP and OpenLDAP it cannot handle multiple
lists with the same attribute name (in this case objectclass). This does
work with Netscape's directory server though. 

For those that care, I modified addLdif so it looks something like this,
please bear in mind my inexperience (blatantly obvious I'm sure) with
Python:

def addLdif(ldapConn, dn, fileName):
   print "Entering addLdif()"
   try:
      dataFile = open(fileName, 'r')
   except:
      print "Error opening ldif file '" + fileName + "'"
      print "Aborting installation!"
      sys.exit()

   fileData = dataFile.readlines()
   dataFile.close()

   ldapData = []
   ldapDataDictionary = {}

   for line in fileData:
      index = string.find(line, ':')
      attributeName = subString(line,0,index)
      attributeValue = string.strip(subString(line,index+1))
  
      if attributeName in ldapDataDictionary.keys():

         # make "deep" copy, reference copy gets screwed up somehow
         tempList = []
         for atr in ldapDataDictionary[attributeName]:
            tempList.append(atr)
         tempList.append(attributeValue)

         ldapDataDictionary[attributeName] = tempList
      else:
         ldapDataDictionary[attributeName] = [ attributeValue ]

   for key in ldapDataDictionary.keys():
      ldapData = ldapData + [( key, ldapDataDictionary[key]), ]

   try:
      ldapConn.add_s(dn, ldapData)
   except:
      raise


Cheers,
Peter

On Sat, 2002-02-02 at 11:18, Peter van Rensburg wrote:
> Hi 
> 
> I'm using openldap 2.0.22 and the latest Python-LDAP and python 2.2 (I
> also tried with a very old version of Python-LDAP and python 1.5.2 with
> the same results.)
> 
> I stop openldap, rm all the .db files, start openldap, so it's a "fresh"
> install. 
> 
> The LDIF I'm trying to import looks like this:
> 
> dn: o=DOTC
> objectclass: top
> objectclass: organization
> o: DOTC
> 
> Using ldapadd: 
> ~openldap/bin/ldapadd -x -D"cn=Directory Manager,o=DOTC" -w xx -f
> org2.ldif
> 
> works fine without any errors.
> 
> Using a basic python script, something like this:
> 
> import sys
> import os
> import ldap
> import string
> 
> def subString(strinput, begin, end=0):
>    if 0 == end:
>       end = len(strinput)
>    
>    result = ""
>    for i in range(begin,end):
>       result = result + strinput[i]
>    
>    return result
> 
> def addLdif(ldapConn, dn, fileName):
>    print "Entering addLdif()"
>    try:
>       dataFile = open(fileName, 'r')
>    except:
>       print "Error opening ldif file '" + fileName + "'"
>       print "Aborting installation!"
>       sys.exit()
> 
>    print "reading lines"
>    fileData = dataFile.readlines()
>    dataFile.close()
>    print "done reading lines"
> 
>    ldapData = []
> 
>    print "constructing _ldapData"
>    print 
>    for line in fileData:
>       print "looking at line: " + line
>       index = string.find(line, ':')
>       ldapData = ldapData + [(subString(line,0,index),
> [string.strip(subString(line,index+1))]), ]
> 
>    print "_ldapData = " 
>    print ldapData
>    
>    try:
>       ldapConn.add_s(dn, ldapData)
>    except:
>       raise
> 
> def main(argv):
>    try:
>       ldapObj = ldap.open("localhost", 389)
>       ldapObj.simple_bind_s("cn=Directory Manager,o=DOTC", "xx")
>    except:
>       print "[main] Ldap open or bind failed!!"
>       return 0
> 
>    #try:
>    addLdif(ldapObj, "o=DOTC", "org2.ldif")
>    #except:
>    #   print "[main] addLdif failed!!"
>    #   return 0
> 
>  
> if __name__ == '__main__':
>    sys.exit(main(sys.argv))
> 
> produces the following error:
> 
>   File "/usr/local/lib/python2.2/site-packages/ldap/ldapobject.py", line
> 121, in add_s
>     self.result(msgid)
>   File "/usr/local/lib/python2.2/site-packages/ldap/ldapobject.py", line
> 355, in result
>     ldap_result = self._ldap_call(self._l.result,msgid,0,0)
>   File "/usr/local/lib/python2.2/site-packages/ldap/ldapobject.py", line
> 59, in _ldap_call
>     result = ldap._ldap_call(func,*args,**kwargs)
>   File "/usr/local/lib/python2.2/site-packages/ldap/__init__.py", line
> 31, in _ldap_call
>     result = apply(func,args,kwargs)
> ldap.UNDEFINED_TYPE: {'info': 'dn: attribute type undefined', 'desc':
> 'Undefined attribute type'}
> 
> The first line in the LDIF being "dn: blabla" is specified in the RFC
> for LDIFs. If I remove that line (dn: o=DOTC) I get the following error:
> 
>   File "/usr/local/lib/python2.2/site-packages/ldap/ldapobject.py", line
> 121, in add_s
>     self.result(msgid)
>   File "/usr/local/lib/python2.2/site-packages/ldap/ldapobject.py", line
> 343, in result
>     ldap_result = self._ldap_call(self._l.result,msgid,0,0)
>   File "/usr/local/lib/python2.2/site-packages/ldap/ldapobject.py", line
> 59, in _ldap_call
>     result = ldap._ldap_call(func,*args,**kwargs)
>   File "/usr/local/lib/python2.2/site-packages/ldap/__init__.py", line
> 31, in _ldap_call
>     result = apply(func,args,kwargs)
> ldap.TYPE_OR_VALUE_EXISTS: {'info': 'attribute provided more than once',
> 'desc': 'Type or value exists'}
> 
> 
> This works fine (without the "dn: blabla" at the start of the ldif) with
> IPlanet/Netscape's directory server. 
> 
> Does anyone know what is going on here?
> 
> Many thanks,
> Peter
> 






More information about the python-ldap mailing list