포스트

[트러블 슈팅] redis에서 파이썬으로 json 데이터 읽어오기

1. 문제 원인

Redis에 저장된 Key - Value 값이 있다. Key는 정수고 Value는 json 값이다.

1
2
3
4
5
6
Key: 1
Value: {
	"answer_num": 2,
	"answer": "fffffff",
	"question": "안녕하세요"
}

다음과 같은 문제들이 있었다.

  1. 이때 Value를 불러오고 싶은데 계속 String 형식으로 불러와지는 현상이 있었다.
  2. String 형식으로 불러온 값도 한글이 유니코드로 변환돼 이상한 값으로 불러와졌다. + 이상한 역슬래시가 붙어있다.

오류 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
  {
    "key": "2",
    "value": "\"{\\\"answer_num\\\": 1, \\\"answer\\\": \\\"\\\\ud638\\\\uc774\\\\ud638\\\\uc774\\\", \\\"user_question\\\": \\\"\\\\uc548\\\\ub155\\\\ud558\\\\uc138\\\\uc694\\\"}\""
  },
  {
    "key": "1",
    "value": "\"{\\\"answer_num\\\": 2, \\\"answer\\\": \\\"fffffffff\\\", \\\"user_question\\\": \\\"dffdd\\\"}\""
  },
  {
    "key": "3",
    "value": "\"{\\\"answer_num\\\": 3, \\\"answer\\\": \\\"\\\\uadf8\\\\ub807\\\\uad70\\\\uc694\\\", \\\"user_question\\\": \\\"\\\\ubc18\\\\uac00\\\\uc6cc\\\\uc694\\\"}\""
  }
]

redis에 담겨있는 모든 key를 검색한 후 리스트에 담아 반환했다.

내가 원한 것은 json str으로 저장되어 있으니 json으로 바로 불러와서 활용하고 싶었다.

오류 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
async def get_users_query():
    rd = redis_config()
    result = []

    cursor = '0'
    while cursor != '0':
        cursor, keys = rd.scan(cursor=cursor, match='*')
        for key in keys:
            value = rd.get(key)
            # 값을 UTF-8로 디코딩하고 JSON으로 변환
            decoded_value = value.decode('utf-8')
            json_value = json.dumps(decoded_value, ensure_ascii=False)
            result.append({
                'key': key.decode('utf-8'),
                'value': json_value
            })

    if result:
        result.pop()  # 마지막 요소 제거

    return result

1.1 Python json dumps vs loads

파이썬에서 json str을 다룰때는 json 모듈을 사용한다.

기본 파이썬에선 json 자료형은 존재하지 않으니, db에서 읽어온 json str 값들을 프론트엔드 쪽에서 쉽게 사용하기 위해선 파이썬 딕셔너리로 전달해주는 것이 좋다.

이때 내가 위에서 사용한 json dumps()파이썬 딕셔너리를 string 값으로 가져오는 함수이다. 즉 위 코드에서 하는 일은 불러온 string을 다시 string으로 이중 인코딩하는 뻘짓이었다…

db에서 읽어온 json str을 파이썬 딕셔너리로 변환하기 위해선 json loads 가 사용되어야 한다.

2. 해결

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
async def get_users_query():
    rd = redis_config()
    result = []

    cursor = '0'
    while cursor != 0:
        cursor, keys = rd.scan(cursor=cursor, match='*')
        for key in keys:
            value = rd.get(key)
            decoded_value = value.decode('utf-8')
            json_value = json.loads(decoded_value)
            result.append({
                'key': key,
                'value': json_value
            })

    if result:
        result.pop()
    return result

json loads() 를 사용하니 간단하게 해결됐다.

Redis 는 key - value로 사용 가능하고, value의 값에 json str도 저장 가능하니 json을 불러와 값을 전달할때는 json loads를 사용하면 된다.



이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.