0

I'm a bit new to Python Classes. I worked with python but not extensively with classes. So here is what I'm trying to do, is to read a JSON and convert the elements and nodes to a class and object, so I call functions to get values from the JSON.

{
  "datamap": {
    "version": "1.0",
    "sourceProvider": "example_provider",
    "logicalTables": [
      {
        "name": "region_table_one",
        "physicalTable": "dbo_parent_user", 
        "logicalColumns": [
          {
            "name": "UID",
            "physicalColumnName": "uid_number",
            "displayName": "U Number",
            "logicalDataType": "integer",
            "inputType": {
              "inputAction": "number",
              "multiSelect": false
            },
          },
          {
            "name": "UID1",
            "physicalColumnName": "uid_number1",
            "displayName": "U Number1",
            "logicalDataType": "integer",
            "inputType": {
              "inputAction": "number",
              "multiSelect": false
            },
          },
        ]
      },
      {
        "name": "region_table_two",
        "physicalTable": "dbo_user_two", 
        "logicalColumns": [
          {
            "name": "UID2",
            "physicalColumnName": "uid_number2",
            "displayName": "U Number2",
            "logicalDataType": "integer",
            "inputType": {
              "inputAction": "number",
              "multiSelect": false
            },
          },
          {
            "name": "UID3",
            "physicalColumnName": "uid_number3",
            "displayName": "U Number3",
            "logicalDataType": "integer",
            "inputType": {
              "inputAction": "number",
              "multiSelect": false
            },
          },
        ]
      }
    ]
  }
}

The Python Class I wrote:

import json

class DataMap(object):
    def __init__(self):
        with open('datamap.json') as f:
            self.__dict__ = json.load(f)

    def get_logical_table(self, tableName):
        if self.datamap['logicalTables']['name'] == tableName:
            return datamap['logicalTables']['name']

obj = DataMap()
print(obj.datamap['logicalTables'])
#print(obj.get_logical_table('logicalTables'))

  • What I'm trying to do is if I call get_logical_table I should be able to get region_table_one and region_table_two.
  • is there any way that if I pass get_logical_table output to get the logicalColumns inside that JSON object.

I'm referencing:
- https://thepythonguru.com/reading-and-writing-json-in-python/ - Deserialize a json string to an object in python To some extent, but stuck with reading notes to a class. Thanks for the help in advance.

Update:

import json


class DataMap(object):
    def __init__(self):
        self.logical_tables = None
        with open('datamap.json') as f:
            self.__dict__ = json.load(f)
        self.data_map = self.__dict__['datamap']

    def get_map_id(self):
        return self.data_map['mapId']

    def get_version(self):
        return self.data_map['version']

    def get_region(self):
        return self.data_map['region']

    def get_source_provider(self):
        return self.data_map['sourceProvider']

    def __getitem__(self, key):
        return self.data_map[key]

    def __repr__(self):
        return repr(self.data_map)

    def __len__(self):
        return len(self.__dict__['datamap'])

    def copy(self):
        return self.data_map.copy()

    def has_key(self, k):
        return k in self.data_map

    def keys(self):
        return self.data_map.keys()

    def values(self):
        return self.data_map.values()

    def items(self):
        return self.data_map.items()

    def pop(self, *args):
        return self.data_map.pop(*args)

    def __contains__(self, item):
        return item in self.data_map

    def __iter__(self):
        return iter(self.data_map)


class LogicalTables(DataMap):
    def __init__(self):
        DataMap.__init__(self)
        self.logical_tables = self.data_map['logicalTables']

        logical_table = None
        for table in self.get_all_logical_tables():
            self.name = table.get("name")
        print(self.name)

    def __len__(self):
        return len(self.data_map['logicalTables'])

    def __repr__(self):
        return repr(self.logical_tables)

    def createName(self):
        self.name = "Temporary Value"

    def has_key(self, k, table_name=None):
        """Check if the dict has given key"""
        logical_table = self.get_logical_table(table_name)
        return k in logical_table

    def get_all_logical_tables(self, tableName=None):
        return self.data_map['logicalTables']

    def get_logical_table(self, table_name=None):
        logical_table = None
        for table in self.get_all_logical_tables():
            if table.get("name") == table_name:
                logical_table = table
        return logical_table

    def get_logical_table_list(self, table_name=None):
        table_list = []
        for table in self.get_all_logical_tables():
            table_list.append(table.get("name"))
        return table_list


class LogicalColumns(LogicalTables):
    def __init__(self):
        LogicalTables.__init__(self)
        self.logical_columns = self.logical_tables['logicalColumns']

    def __len__(self):
        return len(self.logical_columns['logicalColumns'])

    def __repr__(self):
        return repr(self.logical_columns)

I have updated and this is my current class.

DonOfDen
  • 3,968
  • 11
  • 62
  • 112

1 Answers1

2

logicalTables in your json input is actually a list, not a dict, so you doing ['logicalTables']['name'] won't work.

You need to change get_logical_table to something like this:

    def get_logical_table(self, tableName):
        for table in self.datamap['logicalTables']:
            if table['name'] == tableName:
                return table['logicalColumns']

Instead of iterating through lists, it would be better to transform your dict so you could directly access any logicalTable with its name (if they are unique).

Update:

You can transform the dict like so:

tables = {}
for table in self.datamap['logicalTables']:
    name = table['name']
    del table['name']
    tables[name] = table

self.datamap['logicalTables'] = tables

# Use like so:
table_one = self.datamap['logicalTables']['region_table_one']
GordonAitchJay
  • 4,640
  • 1
  • 14
  • 16
  • How can i `transform to dict` any examples available online? @Gordon – DonOfDen Mar 15 '20 at 10:21
  • I have made some modifications so far. – DonOfDen Mar 15 '20 at 10:24
  • I would want `self.datamap['logicalTables']` to be a `dict`, with the keys being the `name` of each `logicalTables` item, and the value being the table (probably without the `name` item, as it's unnecessary). Again, the names must be unique for this to work. – GordonAitchJay Mar 15 '20 at 10:33
  • Yes, we can modify the `datamap`, as I'm defining it myself. they keys will be unique always. – DonOfDen Mar 15 '20 at 10:35
  • 1
    I've updated my answer to show you how to transform the dict. Obviously it's up to you exactly how you change it, if at all. – GordonAitchJay Mar 15 '20 at 10:41
  • I get the point but the problem is how can i get multiple class values, if u could have a look at my updated class, i think you might understand what im trying to achieve. – DonOfDen Mar 15 '20 at 10:45
  • *"how can i get multiple class values"* What class values do you want to get? Which class? Are you referring to `self.datamap`? – GordonAitchJay Mar 15 '20 at 10:50
  • i wanted to set values to `LogicalTables`, `LogicalColumns` and in run time I should be able to get the values using `DataMap` class. Is there any way i can set the values and get it in run time. its a `datamap` so i want to refer it in run time. – DonOfDen Mar 15 '20 at 10:53