Maria DB Data Type Error 해소 방법 공유 - smilebulee/infogen_ims GitHub Wiki
Maria DB 연동시 테이블 컬럼타입이 Date타입이고, 해당 일이 실제 Date 형식으로 값이 넘어오는 경우, Type Error가 발생.
Date 값이 datetime.date(YYYY, MM, DD) 패턴으로 리턴되는데, datetime.date 를 json으로 파싱하는 과정에서 Error가 발생함.
Exception Log
Traceback (most recent call last):
File "/root/.local/lib/python3.6/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/root/.local/lib/python3.6/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/root/.local/lib/python3.6/site-packages/flask_restful/__init__.py", line 272, in error_router
return original_handler(e)
File "/root/.local/lib/python3.6/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/root/.local/lib/python3.6/site-packages/flask/_compat.py", line 38, in reraise
raise value.with_traceback(tb)
File "/root/.local/lib/python3.6/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/root/.local/lib/python3.6/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/root/.local/lib/python3.6/site-packages/flask_restful/__init__.py", line 272, in error_router
return original_handler(e)
File "/root/.local/lib/python3.6/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/root/.local/lib/python3.6/site-packages/flask/_compat.py", line 38, in reraise
raise value.with_traceback(tb)
File "/root/.local/lib/python3.6/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/root/.local/lib/python3.6/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/root/.local/lib/python3.6/site-packages/flask_restful/__init__.py", line 472, in wrapper
return self.make_response(data, code, headers=headers)
File "/root/.local/lib/python3.6/site-packages/flask_restful/__init__.py", line 501, in make_response
resp = self.representations[mediatype](data, *args, **kwargs)
File "/root/.local/lib/python3.6/site-packages/flask_restful/representations/json.py", line 21, in output_json
dumped = dumps(data, **settings) + "\n"
File "/usr/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/lib/python3.6/json/encoder.py", line 201, in encode
chunks = list(chunks)
File "/usr/lib/python3.6/json/encoder.py", line 428, in _iterencode
yield from _iterencode_list(o, _current_indent_level)
File "/usr/lib/python3.6/json/encoder.py", line 325, in _iterencode_list
yield from chunks
File "/usr/lib/python3.6/json/encoder.py", line 404, in _iterencode_dict
yield from chunks
File "/usr/lib/python3.6/json/encoder.py", line 437, in _iterencode
o = _default(o)
File "/usr/lib/python3.6/json/encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'date' is not JSON serializable
app.py 소스 내 다음 소스 추가. 1
import datetime
from json import JSONEncoder
class DateTimeEncoder(JSONEncoder):
# Override the default method
def default(self, obj):
if isinstance(obj, (datetime.date, datetime.datetime)):
return obj.isoformat()
app.py 소스 내 다음 소스 추가. 2
// 실제 app.py에서 retrun 시켜주는 구문에 위 선언한 class 적용.
기존 : return result2
변경후 : json.dumps(result2, indent=4, cls=DateTimeEncoder)
class wrkTimeInfoByEml(Resource): # Mariadb 연결 진행
def get(self):
data = request.get_json()
logging.debug('================== App Start ==================')
logging.debug(data)
logging.debug(data["email"])
logging.debug('================== App End ==================')
#requirements pymysql import 후 커넥트 사용
mysql_con = pymysql.connect(host='218.151.225.142', port=3306, db='IFG_IMS', user='ims2', password='1234',
charset='utf8')
try:
with mysql_con.cursor(pymysql.cursors.DictCursor) as cursor:
#쿼리문 실행
sql = "SELECT * FROM TB_WRK_TM_MGMT_M WHERE EMP_EMAL_ADDR = '" + data["email"] + "'"
logging.debug(sql)
cursor.execute(sql)
finally:
mysql_con.close()
result2 = cursor.fetchall()
for row in result2:
logging.debug('====== row====')
logging.debug(row)
logging.debug('===============')
array = list(result2) # 결과를 리스트로
# return result2
return json.dumps(result2, indent=4, cls=DateTimeEncoder) //indent Option은 로그확인시 들여쓰기 적용으로 파라미터 식별이 편하도록 하는 옵션.
하지만 기존 result2 로깅시 [{'param':'value'}...] 형태로 출력되나,
json.dumps 적용 후 로깅시 [{"param":"value"}...] 형태로 출력된다. (Single Quete --> Double quote)
이 경우, Web Html 에서 데이터출력의 형태가 변경되므로 views.py에서 변환처리 한다.
views.py 소스 내 다음 소스 추가. 1
import ast
views.py 소스 내 다음 소스 추가. 2
// 실제 views.py에서 retrun 시켜주는 구문 변경
기존 : return JsonResponse(r.json(), safe=False)
변경후 : return JsonResponse(ast.literal_eval(r.json()), safe=False)
def getWrkTimeInfoByEml(request):
param = json.loads(request.GET['param'])
logger.info("Parameters Start")
logger.info(param)
logger.info("Parameters End")
# api 호출
r = requests.get('http://dili_api:5006/wrkTimeInfoByEml', json=param)
logger.info(r)
logger.info(r.text)
logger.info(logger.info(ast.literal_eval(r.json())))
logger.info(json.loads(r.text))
# return JsonResponse(r.json(), safe=False)
return JsonResponse(ast.literal_eval(r.json()), safe=False)