[Python-de] Re: Umwandlung ADO Recordset in Dictionary

Diez B. Roggisch deets at web.de
Mit Jun 1 16:02:40 CEST 2005


Am Mittwoch, 1. Juni 2005 15:21 schrieb Andreas Kaiser:
> > Also schreib das erstmal so wie du es machen würdest, poste den code
> > - und dann zerreissen wir dich in der Luft und machen es schöner :)
>
> oRS ist das Recordset:
>
> counter = 0
> # Endergebnis
> content_dict = {}
> while not oRS.EOF:
>      # Dict mit Feldnamen
>      fields_dict = {}
>      # über alle Felder {Feldname0: Feldwert0, ...}
>      for x in range(oRS.Fields.Count):
>          fields_dict[oRS.Fields.Item(x).Name] =
>                  oRS.Fields.Item(x).Value
>      # zusammnbauen Ergebnis
>      content_dict[counter] =  fields_dict
>      # nächster Datensatz aus Recordset
>      oRS.MoveNext()
>      counter = counter + 1
>
> Nun zerreisst mich ;-)

Gerne. Zuerstmal fällt auf das du die Namen immer holst - einmal reicht. Und 
dann das von mir schon angegebene idiom einsetzen. Ausserdem fällt auf, das 
du ein dict von Integer -> Dict benutzt für content-dict. Das mach wenig Sinn 
- nimm da eine Liste.

result = []
if not oRS.EOF:
    width = oRS.Fields.Count
    namen =  [oRS.Fields.Item(x).Name for x in xrange(width)]
    while not oRS.EOF:
          result.append(dict([(name, oRS.Fields.Item(x).Value) for name, x in\
                 zip(namen, xrange(width))]))
          oRS.MoveNext()

So etwa. Besser sähe das ganze aber aus, wenn man sich einen Wrapper um oRS 
baut, der dessen Verhalten pythonischer macht. So in etwa (völlig ungetestet 
und aussem Kopp):

class RSWrapper:

    def __init__(self, rs):
         self._rs = rs
         self._width = oRS.Fields.Count
         self._names = []
         if not rs.EOF:
             self._names =  [rs.Fields.Item(x).Name for x in xrange(width)]

    def __iter__(self):
        return self

    def next(self):
       if self._rs.EOF:
            raise StopIteration
       values = [self._rs.Fields.Item(x).Value for x in xrange(self._width)]
       self._rs.MoveNext()
       return dict(zip(self._names, values)

Dann kann man das oben so schreiben:

result = [row for row in RSWRapper(oRS)]

Hoffe ich....


MfG Diez