Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to construct a "complex" data structure in Python

I need to construct a tool that will be used to create field mappings (between tables) in the most automated manner possible.

Here is the deal: imagine a table being appended to other. (lets ignore field type, just for a second...)

CREATE OR REPLACE TABLE fooA(
id,
name,
type,
foo)

CREATE OR REPLACE TABLE otherFooTable(
idFoo,
nameFoo,
spam)

I am thinking to create a structure like this:

fieldMap = {'otherFooTable': [('idFoo','id'),('nameFoo','name'),('spam','foo')]}

I would be able to access this using (for example)

print fieldMap['tabelax'][0][1]

It´s not a very complex structure, but i can run into some problems using it? Is there any suggestions of how to handle this sort of issue? I need to store (for now) at least inputTable (i don´t want to repeat it for each field mapped), inputField,outputField. There is no reason to store outputTable, because that is always known beforehand.

Suggestions and past experiences are deeply appreciated.

PS: perhaps a formal structure (like a class) would be better?

Thanks

like image 308
George Silva Avatar asked Dec 10 '22 18:12

George Silva


2 Answers

I'd honestly just take hints from (or use) SQLAlchemy or Django Models. These are tried and true data representation methods.

like image 178
geowa4 Avatar answered Dec 26 '22 17:12

geowa4


Here is a little wrapper class for FooB's to mimic FooA's, but still retain their FooB-ishness.

from collections import namedtuple

# use namedtuple to define some simple classes (requires Py2.6 or later)
FooA = namedtuple('FooA', 'id name type foo')
FooB = namedtuple('FooB', 'idfoo namefoo spam')

# create a wrapper class for FooB's to look like a FooA
class FooAMimic(object):
    attrMap = dict(zip(FooA._fields, FooB._fields))
    # or if the fields aren't nicely ordered, declare this mapping explicitly
    #~ attrMap = { 'id' : 'idfoo', 'name' : 'namefoo', 'foo' : 'spam' }
    def __init__(self, obj):
        self.obj = obj
    def __getattr__(self, aname):
        ob = self.obj
        if aname in self.attrMap:
            return getattr(ob, self.attrMap[aname])
        elif  hasattr(ob, aname):
            return getattr(ob, aname)
        else:
            raise AttributeError("no such attribute " + aname)
    def __dir__(self):
        return sorted(set(dir(super(FooAMimic,self)) 
                          + dir(self.obj) 
                          + list(FooA._fields)))

Use it like this:

# make some objects, some FooA, some FooB
fa = FooA('a', 'b', 'c','d')
fb = FooB('xx', 'yy', 'zz')
fc = FooA('e', 'f', 'g','h')

# create list of items that are FooA's, or FooA lookalikes
coll = [fa, FooAMimic(fb), fc]

# access objects like FooA's, but notice that the wrapped FooB
# attributes are still available too
for f in sorted(coll, key=lambda k : k.id):
    print f.id, '=', 
    try:
        print f.namefoo, "(really a namefoo)"
    except AttributeError:
        print f.name

Prints:

a = b
e = f
xx = yy (really a namefoo)
like image 25
PaulMcG Avatar answered Dec 26 '22 17:12

PaulMcG