pynecone를 활용한 table 만들기 ( 내가 만든 커스텀 )

2023. 5. 14. 23:07it

반응형

 
나는 주로 쓰는 데이터베이스는 mongodb 이다. mongodb는 알다 싶이 json 형태로 아주 복잡한 구조의 데이터를 가지게 된다. 그래서 해당 데이터를 누구나 쉽게 table로 만드는 방법을 생각하다가 해당 함수를 만들었다.
 
해당 함수는 복잡한 json 구조를 스스로 파싱해, pynecone의 table로 만들어 전달해 주는 함수이다.  해당 함수는 복잡한 json의 구조를 신경쓰지 않아도 되는 장점이 있다. 내가 필요해서 만들었지만, 다른 사람들도 해당 함수를 쓰면 좋을 거 같아서 한번 만들어 보았다. 
 
나는 참고로 웹 개발자가 아니다. 데이터엔지니어다. 그러니, 해당 함수가 표준과 달라도 크게 비판하지 말아라
 
테스트한 데이터 포멧은 다음과 같다. 테스트 할 때, 최대한 복잡한 모양의 데이터를 만들었다. 

    data = [
            {'a' : 1, 'b' : 2, 'c' : 3, 'd' : [{'e' : 4, 'f' : 5, 'z' : {'a' : 1}},{'e' : 4, 'f' : 5, 'z' : {'a' : 1}}], 'g' : {'h' : 6, 'i' : 7} },
            {'a' : 1, 'b' : 2, 'c' : 3, 'd' : [{'e' : 4, 'f' : 5, 'z' : {'a' : 1}},{'e' : 4, 'f' : 5, 'z' : {'a' : 1}}], 'g' : {'h' : 6, 'i' : 7} },
            {'a' : 1, 'b' : 2, 'c' : 3, 'd' : [{'e' : 4, 'f' : 5, 'z' : {'a' : 1}},{'e' : 4, 'f' : 5, 'z' : {'a' : 1}}], 'g' : {'h' : 6, 'i' : 7} },
        ]

 
pandas로 해당 데이터를 보면 아래와 같다. josn 안에 josn이 있는 복잡한 구조로 만들었다. 
 

 
내가 원하는 테이블 구조는 다음과 같다. row안에 json이 포함된 경우, accordion를 활용해 데이터를 보여준다. 

 
예를 들어 'd'를 클릭하면 아래와 같이 숨겨진 데이터가 뿌려진다.
 

 
그리고 row  안에 또 json 데이터 있으면, accordion를 활용해 묶어서 처리한다. 
예를 들어 'd' 안에 'z' 데이터를 누르면 'z'에 숨겨진 데이터가 보여진다.

 
목표한 화면은 설명이 끝났다. 
 
이제 함수를 설명하겠다. 

def sample006() : 
    def json_to_pynecone_format( data ) : 
        result = {}
        result['header'] = {}
        result['value'] = []
        
        for row in data : 
            tmp_header:list = list(data[0].keys())
            tmp_value:list  = []

            for key in tmp_header:
                if type(row[key]) in [str, int, float] : 
                    tmp_value.append( row[key] )
                else : 
                    if type(row[key]) == list : 
                        tmp_value.insert( len(tmp_value), pc.accordion(items=[ (key, json_to_pynecone_format(row[key]) ) ] ) )
                    elif type(row[key]) == dict : 
                        tmp_value.insert( len(tmp_value), pc.accordion(items=[ (key, json_to_pynecone_format( [row[key]] ) ) ] ) )
                    
            
            result['header'] = tmp_header
            result['value'].append( tmp_value ) 

        return  pc.table( headers= result['header'], rows= result['value'] ) 


    data = [
            {'a' : 1, 'b' : 2, 'c' : 3, 'd' : [{'e' : 4, 'f' : 5, 'z' : {'a' : 1}},{'e' : 4, 'f' : 5, 'z' : {'a' : 1}}], 'g' : {'h' : 6, 'i' : 7} },
            {'a' : 1, 'b' : 2, 'c' : 3, 'd' : [{'e' : 4, 'f' : 5, 'z' : {'a' : 1}},{'e' : 4, 'f' : 5, 'z' : {'a' : 1}}], 'g' : {'h' : 6, 'i' : 7} },
            {'a' : 1, 'b' : 2, 'c' : 3, 'd' : [{'e' : 4, 'f' : 5, 'z' : {'a' : 1}},{'e' : 4, 'f' : 5, 'z' : {'a' : 1}}], 'g' : {'h' : 6, 'i' : 7} },
        ]
    return json_to_pynecone_format( data )

 
재귀함수를 사용했다. json를 만나면, 재귀함수로 자기 자신을 호출한다. 그렇게 테이블 안에 테이블이 있는 구조로 설계를 했다. if 문을 활용해서 str, int, float를 제외한 다른 타입은 자기 자신을 호출한다. 
 
만약, pandas dataframe를 활용해서 해당 함수로 데이터를 뿌리고 싶으면, data.to_dict('recode') 를 활용해 사용하면 된다. 

import pandas as pd

data = [
            {'a' : 1, 'b' : 2, 'c' : 3, 'd' : [{'e' : 4, 'f' : 5, 'z' : {'a' : 1}},{'e' : 4, 'f' : 5, 'z' : {'a' : 1}}], 'g' : {'h' : 6, 'i' : 7} },
            {'a' : 1, 'b' : 2, 'c' : 3, 'd' : [{'e' : 4, 'f' : 5, 'z' : {'a' : 1}},{'e' : 4, 'f' : 5, 'z' : {'a' : 1}}], 'g' : {'h' : 6, 'i' : 7} },
            {'a' : 1, 'b' : 2, 'c' : 3, 'd' : [{'e' : 4, 'f' : 5, 'z' : {'a' : 1}},{'e' : 4, 'f' : 5, 'z' : {'a' : 1}}], 'g' : {'h' : 6, 'i' : 7} },
        ]

data = pd.DataFrame( data )

data.to_dict('recode')

 
 
 

반응형