파이썬을 사용하여 오라클 데이터베이스에 배치 삽입을 수행하려면 어떻게 해야 합니까?
Oracle 데이터베이스 테이블에 삽입하고 싶은 월간 날씨 데이터가 몇 개 있지만 보다 효율적으로 사용하기 위해 해당 기록을 일괄적으로 삽입하고 싶습니다.Python에서 이 작업을 수행하는 방법에 대해 조언할 수 있는 사람이 있습니까?
예를 들어, 내 표에 스테이션 ID, 날짜 및 두 개의 값 필드의 네 개의 필드가 있다고 가정해 보겠습니다.레코드는 스테이션 ID 및 날짜 필드(합성 키)로 고유하게 식별됩니다.각 스테이션에 대해 입력해야 하는 값은 X개의 전체 연도 값이 있는 목록에 유지되므로, 예를 들어 2년 값이 있는 경우 값 목록에는 24개의 값이 포함됩니다.
레코드를 한 번에 하나씩 삽입하려면 다음과 같이 해야 합니다.
connection_string = "scott/tiger@testdb"
connection = cx_Oracle.Connection(connection_string)
cursor = cx_Oracle.Cursor(connection)
station_id = 'STATION_1'
start_year = 2000
temps = [ 1, 3, 5, 7, 9, 1, 3, 5, 7, 9, 1, 3 ]
precips = [ 2, 4, 6, 8, 2, 4, 6, 8, 2, 4, 6, 8 ]
number_of_years = len(temps) / 12
for i in range(number_of_years):
for j in range(12):
# make a date for the first day of the month
date_value = datetime.date(start_year + i, j + 1, 1)
index = (i * 12) + j
sql_insert = 'insert into my_table (id, date_column, temp, precip) values (%s, %s, %s, %s)', (station_id, date_value, temps[index], precips[index]))
cursor.execute(sql_insert)
connection.commit()
효율성을 높이기 위해 일괄 삽입을 수행하는 방법 외에 위에서 수행하는 방법이 있습니까?참고로 제 경험은 Java/JDBC/Hibernate이므로 누군가가 Java 접근 방식과 비교한 설명/예시를 제공할 수 있다면 특히 도움이 될 것입니다.
편집: 커서를 사용해야 할 것 같습니다.여기에 설명된 바와 같이 많은 것을 실행합니까?
제안, 의견 등에 대해 미리 감사드립니다.
잘 작동하는 것으로 보이는 것은 다음과 같습니다(그러나 이를 개선할 수 있는 방법이 있다면 의견을 제시해 주십시오)
# build rows for each date and add to a list of rows we'll use to insert as a batch
rows = []
numberOfYears = endYear - startYear + 1
for i in range(numberOfYears):
for j in range(12):
# make a date for the first day of the month
dateValue = datetime.date(startYear + i, j + 1, 1)
index = (i * 12) + j
row = (stationId, dateValue, temps[index], precips[index])
rows.append(row)
# insert all of the rows as a batch and commit
ip = '192.1.2.3'
port = 1521
SID = 'my_sid'
dsn = cx_Oracle.makedsn(ip, port, SID)
connection = cx_Oracle.connect('username', 'password', dsn)
cursor = cx_Oracle.Cursor(connection)
cursor.prepare('insert into ' + database_table_name + ' (id, record_date, temp, precip) values (:1, :2, :3, :4)')
cursor.executemany(None, rows)
connection.commit()
cursor.close()
connection.close()
사용하다Cursor.prepare()
그리고.Cursor.executemany()
.
cx_Oracle 설명서에서 다음을 수행합니다.
Cursor.prepare
(문[, 태그])실행() 호출 전에 실행할 문을 정의할 수 있습니다.이렇게 하면 실행() 호출이 없음 또는 문과 동일한 문자열 개체로 이루어질 때 준비 단계가 수행되지 않습니다. [...]
Cursor.executemany
(문, 매개변수)데이터베이스에 대해 실행할 문을 준비한 다음 시퀀스 매개 변수에 있는 모든 매개 변수 매핑 또는 시퀀스에 대해 실행합니다.문은 execute() 메서드가 관리하는 것과 동일한 방식으로 관리됩니다.
따라서 위의 두 가지 기능을 사용하면 코드가 다음과 같이 됩니다.
connection_string = "scott/tiger@testdb"
connection = cx_Oracle.Connection(connection_string)
cursor = cx_Oracle.Cursor(connection)
station_id = 'STATION_1'
start_year = 2000
temps = [ 1, 3, 5, 7, 9, 1, 3, 5, 7, 9, 1, 3 ]
precips = [ 2, 4, 6, 8, 2, 4, 6, 8, 2, 4, 6, 8 ]
number_of_years = len(temps) / 12
# list comprehension of dates for the first day of the month
date_values = [datetime.date(start_year + i, j + 1, 1) for i in range(number_of_years) for j in range(12)]
# second argument to executemany() should be of the form:
# [{'1': value_a1, '2': value_a2}, {'1': value_b1, '2': value_b2}]
dict_sequence = [{'1': date_values[i], '2': temps[i], '3': precips[i]} for i in range(1, len(temps))]
sql_insert = 'insert into my_table (id, date_column, temp, precip) values (%s, :1, :2, :3)', station_id)
cursor.prepare(sql_insert)
cursor.executemany(None, dict_sequence)
connection.commit()
Oracle의 마스터링 Oracle+도 참조하십시오.Python 기사 시리즈.
댓글 중 하나에서 언급한 것처럼, 사용을 고려해 보십시오.INSERT ALL
아마도 사용하는 것보다 훨씬 빠를 것입니다.executemany()
.
예:
INSERT ALL
INTO mytable (column1, column2, column_n) VALUES (expr1, expr2, expr_n)
INTO mytable (column1, column2, column_n) VALUES (expr1, expr2, expr_n)
INTO mytable (column1, column2, column_n) VALUES (expr1, expr2, expr_n)
SELECT * FROM dual;
http://www.techonthenet.com/oracle/questions/insert_rows.php
fii 내 테스트 결과:
저는 5000줄에 삽입합니다.행당 3개의 열이 있습니다.
- 인서트를 5000번 실행합니다. 비용은 1.24분입니다.
- 실행 시간은 0.125초입니다.
- 모든 코드를 삽입하여 실행합니다. 비용은 4.08분입니다.
t(a,b,c)에 sql like insert all을 설정하는 파이썬 코드는 듀얼 유니언에서 :1, :2, :3을 선택합니다. 모두 daul에서 :4, :5::6을 선택합니다...
이 긴 SQL을 설정하기 위한 파이썬 코드, 비용은 0.145329초였습니다.
저는 아주 오래된 태양 기계에서 제 코드를 테스트합니다. cpu: 1415 MH.
세 번째 경우, 데이터베이스 측면을 확인했는데, 대기 이벤트는 "SQL*클라이언트의 데이터 추가"입니다.즉, 서버가 클라이언트로부터 더 많은 데이터를 기다리고 있습니다.
세 번째 방법의 결과는 시험 없이는 믿을 수 없습니다.
그래서 제가 제안한 짧은 제안은 단지 경영진을 많이 이용하는 것입니다.
union을 사용하여 큰 SQL 삽입 문을 만듭니다.
insert into mytable(col1, col2, col3)
select a, b, c from dual union
select d, e, f from dual union
select g, h, i from dual
python에서 문자열을 빌드하고 오라클에 하나의 문으로 제공하여 실행할 수 있습니다.
언급URL : https://stackoverflow.com/questions/14904033/how-can-i-do-a-batch-insert-into-an-oracle-database-using-python
'source' 카테고리의 다른 글
합계와 같은 Python 요소별 튜플 작업 (0) | 2023.07.20 |
---|---|
강제 덮어쓰기와 함께 Git 병합 (0) | 2023.07.20 |
Python에서 세트 세트를 만들려면 어떻게 해야 합니까? (0) | 2023.07.20 |
Oracle SQL Developer에서 밑줄을 피하는 방법은 무엇입니까? (0) | 2023.07.20 |
파이썬에서 코드 행 사이에 걸리는 시간을 측정하는 방법은 무엇입니까? (0) | 2023.07.20 |