문제상황: executemany 를 사용하여 insert를 한 번에 처리하고자 함.
정상작동하던 코드가 insert_dts 컬럼을 추가하고자 하니 문제 발생
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import re
RE_INSERT_VALUES = re.compile(
r"\s*((?:INSERT|REPLACE)\b.+\bVALUES?\s*)"
+ r"(\(\s*(?:%s|%\(.+\)s)\s*(?:,\s*(?:%s|%\(.+\)s)\s*)*\))"
+ r"(\s*(?:ON DUPLICATE.*)?);?\s*\Z",
re.IGNORECASE | re.DOTALL,
)
query = f'INSERT IGNORE INTO TABLE_NM (aaa, DTS) VALUES (%s, NOW())'
query2 = f'INSERT IGNORE INTO TABLE_NM (aaa) VALUES (%s)'
m = RE_INSERT_VALUES.match(query)
m2 = RE_INSERT_VALUES.match(query2)
|
cs |
executemany 를 보면 위와 같이 정규식으로 쿼리를 처리 함.
정규식에 안 걸림...
정규식 테스트 할 수 있는 사이트
<기존코드>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
if datas:
columns = list(datas[0].keys())
columns_str = ", ".join([f"{col}" for col in columns])
values_str = ", ".join([f"%({col})s" for col in columns])
insert_dts = datetime.strftime(datetime.now(timezone("Asia/Seoul")), "%Y-%m-%d %H:%M:%S")
query = f'INSERT IGNORE INTO TABLE_NM ({columns_str}, INSERT_DTS) VALUES ({values_str}, NOW())'
logger.debug(query)
try:
conn = DB_connection.db_conn()
cursor = conn.cursor()
cursor.executemany(query, datas)
conn.commit()
result = Result(True)
except MySQLError as err:
logger.error(f"Database Error occurred: {err}")
conn.rollback()
result = Result(False, f"Database Error occurred: {err}")
finally:
if conn.open:
cursor.close()
conn.close()
return result
|
cs |
<수정코드>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
if datas:
columns = list(datas[0].keys())
columns_str = ", ".join([f"{col}" for col in columns] + ["INSERT_DTS"])
values_str = ", ".join(["(" + ", ".join([f"'{data[col]}'" for col in columns] + ["NOW()"]) + ")"for data in datas])
query = f"INSERT IGNORE INTO TABLE_NM ({columns_str}) VALUES\n{values_str}"
logger.debug(query)
try:
conn = DB_connection.db_conn()
cursor = conn.cursor()
cursor.execute(query)
|
cs |
INSERT TABLE(COLUM_NAME) VALUES(DATA), (DATA2),(DATA3) 와 같은 형식으로 쿼리 수정
# COULUMNS_STR 에만 INSERT_DTS 를 추가하여야 합니다. COULUMNS 에서 추가하면 VALUES_STR 를 만드는 과정에서 DATAS 에 INSERT_DTS가 없기 때문에 오류가 발생합니다.
참고사항
1. datas 의 형태는 딕셔너리를 리스트로 감싼 형태입니다.
'IT > Python' 카테고리의 다른 글
| [codility] Greedy TieRopes (0) | 2023.03.29 |
|---|---|
| [codility] Greedy MaxNonoverlappingSegments (0) | 2023.03.29 |
| [Greedy] (0) | 2023.03.29 |
| 두 수의 합 (이중 for문 / 투 포인터 / Hash) (0) | 2023.03.15 |
| [프로그래머스] 파일명 정렬 (안정 정렬이란?) (0) | 2022.08.09 |