import Adsense from ”@/components/Adsense.astro”;
PostgreSQL – 파이썬으로 select and copy 구현 – executemany()
파이썬 라이브러리 psycopg2 를 이용해서 select 구문으로 읽은 데이터를 insert 구문으로 복사해서 넣는 아주 무식한 동작을 해보자. psql 쿼리로 연속적인 대량의 데이터를 처리하는 경우, 그냥 executemany 를 써서 편리하게 이용했다. 간단한 executemany 예제를 볼까?
executemany 예제
사실 이런 예제는 다른 2개의 database 사이에 데이터를 옮길때나 필요하지 쓸일이 없는 것 같긴한데, 많이 쓰니깐 이런 기능이 있었겠지. 암튼
- connection 과 cursor 를 각각 소스와 목적지에 맞게 맞춰두고, 먼저 소스에서 SELECT 구문으로 읽어드린다.
- 이때, 원하는 필드를 순서대로 지정하는 것이 좋다. 넣을때 그대로 넣으면 되니깐
- fetchall() 기능으로 읽을 결과를 리스트에 저장하고,
- 목적지에다가 executemany() 를 통해 일괄 넣어 버린다.
# worktimelog 정보는 아래에 추가for orderitem_id in orderitem_id_list: postgreSQL_select_Query = """SELECT updated_at, created_at, jigcount, jigmanager_id, orderitem_id FROM testxapi_worktimelog WHERE orderitem_id=%s ORDER BY id ASC""" cur_dev_db.execute(postgreSQL_select_Query, (orderitem_id,)) mobile_records = cur_dev_db.fetchall() # 대상 테이블에 추가 sql_insert_query = """ INSERT INTO testxapi_worktimelog (updated_at, created_at, jigcount, jigmanager_id, orderitem_id) VALUES (%s,%s,%s,%s,%s) RETURNING id""" result = cur_final_db.executemany(sql_insert_query, mobile_records) con_final_db.commit()
기초 참고 예제
아래 사이트에서 기본을 배우면 더 쉽게 코드를 이해할 수 있습니다. 위 코드는 아래 사이트에서 예제를 가져다가 수정한 것입니다.
- https://pynative.com/python-postgresql-select-data-from-table/
- https://pynative.com/python-postgresql-insert-update-delete-table-data-to-perform-crud-operations/
성능개선
아래 링크를 읽고 좀 반성. 1회성 일이라 그냥 해 버렸는데 실시간 활용이 필요한 경우 아래 글을 참고하세요.
PostgreSQL – update 시간 interval
현재 저장된 시간에서 몇 시간 앞으로 뒤로 빼거나 더하고 싶다면 interval 함수를 이용하세요.
몇 시간 되돌리기
시간만 되돌리기, 나머지는 그대로 두고 그냥 코드를 보자.
현재 저장 시간에서 한국 시차 적용을 잘못해서 다시 9시간을 뒤로 돌리는 코드</u>
UPDATE public.testxapi_result SET starttime = starttime - interval '9 hours', endtime = endtime - interval '9 hours' where orderitem_id=315;SELECT * FROM public.testxapi_resultwhere orderitem_id=315ORDER BY id DESC LIMIT 100
특정 필드 날짜와 맞추기
생성 날짜와 로그 기록 날짜가 다른 경우, 난감하다. 컴퓨터 시간이 틀렸거나 머 소스 쪽에서 그렇게 보내주면 어쩔 수 없다. 보정이 필요하다.</u>
날짜의 경우에는 시스템 시간을 쓰게 되므로, 좀 이성적인 시간으로 생각하고 분, 초 등의 정보는 남기고 날짜 부분만 바꾸고 싶다면.. 아래 예는 시간 정보까지 바꾸는 것임 (아래 코드의 hour 부분을 day 로 바꾸면 날짜까지만 바꿀 수 있다.)
함수가 딱 없어서 자기 필드에서 날짜를 싹 빼버리고, 그 부분을 다른 필드 값을 더해주는 형태로 구현했다. 짱똘을 좀 굴려야 😂
UPDATE public.testxapi_result SET starttime = starttime - date_trunc('hour', starttime) + date_trunc('hour', created_at), endtime = endtime - date_trunc('hour', endtime) + date_trunc('hour', created_at)where serial='00:08:DC:5E:B6:9C';-- orderitem_id= 200SELECT * from public.testxapi_result where serial='00:08:DC:5E:B6:9C';
결과는,
<figure class=“kg-card kg-image-card”></figure>## 참고 사이트
<figure class=“kg-card kg-bookmark-card”><div class=“kg-bookmark-content”><div class=“kg-bookmark-title”>9.9. Date/Time Functions and Operators</div><div class=“kg-bookmark-description”>9.9. Date/Time Functions and Operators 9.9.1. EXTRACT, date_part 9.9.2. date_trunc 9.9.3. date_bin 9.9.4. AT TIME ZONE 9.9.5. Current Date/Time 9.9.6. Delaying …</div><div class=“kg-bookmark-metadata”><span class=“kg-bookmark-author”>PostgreSQL Documentation
</span>``</div>``</div><div class=“kg-bookmark-thumbnail”></div></figure>> timestamp - interval → timestamp
Subtract an interval from a timestamp
timestamp '2001-09-28 23:00' - interval '23 hours'→2001-09-28 00:00:00
PostgreSQL – WHERE 필터 in 사용법
PostgreSQL 조회 업데이트 시 filtering in 사용하는 방법을 살펴보자.
같은 것을 비교할 때는 그냥 = 키워드를 쓰면 되니, 고민할 것이 없는데 복수 개의 키워드 값과 동일한지 비교하려면 in 을 사용하는 것이 좋다.
볼 것도 없게 쉽게 예제로 파악할 수 있다. in('키워드', '키', ... ) 이렇게 사용하면 된다.
UPDATE public.testxapi_result
SET is_deleted = '2'::integer
WHERE serial in ('00:08:DC:75:5F:3F','00:08:DC:75:46:3A','00:08:DC:75:5C:B0');
간단하게 정리 끝.
참고 페이지
PostgreSQL JSONField 값 입력 방법
그냥 텍스트가 아니라 Query Editor 에서 넣으려고 하는데 “” 이렇게 주니깐 에러 발생
::jsonb 라는 키워드를 붙여줘야 한다.
UPDATE django.app_test_data_manager_testlog SET option_field = '{}'::jsonb;
이 예제의 option_field 의 선언은 다음과 같이 되어 있다.
<figure class=“wp-block-image size-full”></figure>
psycopg2 TextField 값 파일 저장 예제
Python psycopg2를 사용해서 TextField 값을 파일로 저장하는 방법을 알아보겠습니다. TextField는 PostgreSQL에서 긴 텍스트를 저장하는 데 사용하는 데이터 형식입니다. 예를 들어, 블로그 게시물의 내용이나 제품 설명을 저장할 수 있습니다.
Python 코드:
Python
import psycopg2
# PostgreSQL 연결 설정
conn = psycopg2.connect(
host="localhost",
port=5432,
database="mydb",
user="myuser",
password="mypassword",
)
# 테이블에서 데이터 가져오기
cur = conn.cursor()
cur.execute("SELECT text FROM mytable")
# TextField 값 뽑기
for row in cur:
text = row[0]
# 파일에 저장
with open("output.txt", "w") as f:
f.write(text)
# 연결 종료
conn.close()
코드를 사용할 때는 주의하시기 바랍니다. 자세히 알아보기content_copy
설명:
이 예제에서는 다음과 같은 작업을 수행합니다.
- PostgreSQL 연결을 설정합니다.
- 테이블에서 데이터를 가져옵니다.
- TextField 값을 뽑습니다.
- 값을 파일에 저장합니다.
- 연결을 종료합니다.
TextField 값 뽑는 방법:
TextField 값을 뽑으려면 다음 코드를 사용합니다.
Python
text = row[0]
코드를 사용할 때는 주의하시기 바랍니다. 자세히 알아보기content_copy
이 코드는 mytable 테이블의 text 열에서 값을 가져옵니다.
파일에 값 저장하는 방법:
파일에 값을 저장하려면 다음 코드를 사용합니다.
Python
with open("output.txt", "w") as f:
f.write(text)
코드를 사용할 때는 주의하시기 바랍니다. 자세히 알아보기content_copy
이 코드는 output.txt 파일에 text 값을 씁니다.
예시:
다음은 mytable 테이블의 내용입니다.
text |
---- |
This is a blog post. |
This is a product description. |
... |
이 예시에서 mytable 테이블에는 두 개의 행이 있습니다. 첫 번째 행에는 블로그 게시물의 내용이 있고, 두 번째 행에는 제품 설명이 있습니다.
확장:
이 예제를 확장하여 다음과 같은 작업을 수행할 수 있습니다.
- TextField 값을 필터링하거나 정렬할 수 있습니다.
- TextField 값을 JSON 또는 CSV 형식으로 저장할 수 있습니다.
- TextField 값을 여러 파일에 저장할 수 있습니다.
PostgreSQL – 조건에 IN 활용
Where 구문에 같은 것 말고 리스트에 포함된 걸로 조사할 때 사용하는 IN 이 있다.
용례가 갑자기 생각이 안나서 찾아봄
PostgreSQL IN operator examples
https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-in/“
Suppose you want to know the rental information of customer id 1 and 2, you can use the IN operator in the WHERE clause as follows:
`SELECT customer_id, rental_id, return_date `
`FROM rental `
`WHERE customer_id IN (1, 2) `
`ORDER BY return_date DESC;`
PostgreSQL – 필드 내 중복 값 제외 distinct
아래 글 참고
https://dog-developers.tistory.com/130
COLUMN_1의 값이 중복 값 존재 시 중복 값을 제거
SELECT
DISTINCT COLUMN_1
FROM TABLE_NAME;
COLUMN_1 + COLUMN_2의 값이 중복 값 존재 시 중복 값을 제거
SELECT
DISTINCT COLUMN_1 , COLUMN_2
FROM TABLE_NAME;
추가 참고
https://redk.tistory.com/37 – Django ORM distinct()
PostgreSQL – 시간 차이를 초로 변환 SQL
PostgreSQL – 시간 차이를 초로 변환하는 구문이 필요하다.
필드 두개를 빼서, 그것을 초로 변환하면 되는데 PostgreSQL 구문으로 간단하게 처리하고 싶어서 검색
잘 안나오는데,
SELECT date_done, date_start, round(extract(epoch from (date_done::timestamp -date_start::timestamp ))::numeric) as diff
FROM TABLE
where id in ('201','200')
ORDER BY id ASC ;
epoch 함수, round 함수, extract 함수
초로 계산한 결과가 잘 나온다.
참고한 링크는 여기 https://tjdguqdl.tistory.com/38
ORM 중복 제거 – distinct
https://django-orm-cookbook-ko.readthedocs.io/en/latest/duplicate.html
>>> duplicates = User.objects.values(
'first_name'
).annotate(name_count=Count('first_name')).filter(name_count__gt=1)
>>> duplicates
<QuerySet [{'first_name': 'John', 'name_count': 3}]>
여기 링크 글이 좋음 – https://unocoings.tistory.com/12