쉘 파이프라인을 통해 CSV 데이터를 SQLite 테이블에 삽입하는 방법은 무엇입니까?

쉘 파이프라인을 통해 CSV 데이터를 SQLite 테이블에 삽입하는 방법은 무엇입니까?

나는 엄격하게 순수한 CSV 형식으로 결과를 stdout에 출력하는 프로그램을 작성했습니다. (각 줄은 레코드를 나타내며 동일한 쉼표로 구분된 필드 세트를 포함하고 필드에는 소문자 영어 문자, 숫자 및 점만 포함되며 공백은 없고 따옴표도 없습니다. 이스케이프/인코딩해야 할 수 있는 기호는 없습니다.

이 출력을 완벽하게 맞는 SQLite 테이블로 어떻게 리디렉션할 수 있나요?

제약 조건을 위반할지(예: 이미 테이블에 있는 레코드와 동일한 기본/보조 키를 가짐) 기존 레코드를 교체할지 아니면 자동으로 삭제할지 제어할 수 있다면 좋을 것입니다.

물론 프로그램 자체에 직접적인 SQLite 데이터베이스 출력 지원을 구축할 수도 있지만 가능하다면 UNIX 접근 방식을 선호합니다.

답변1

여전히 사용하는 더 간단한 솔루션을 찾았습니다.sqlite3 .import, 그러나 이는 읽거나 임시로 명명된 파이프를 읽지 않습니다 /dev/stdin. 오히려 이와 .import관련이 있다.파이프라인 운영자호출은 cat -표준 입력에서 직접 읽습니다.

#!/bin/bash

function csv_to_sqlite() {
  local database_file_name="$1"
  local table_name="$2"
  sqlite3 -csv $database_file_name ".import '|cat -' $table_name"
}

database_file_name=$1
table_name=$2

csv_to_sqlite "$database_file_name" "$table_name"

이는 Windows 명령 셸에서는 작동하지 않습니다.

답변2

두 가지 방법:

샘플 test.csv파일:

GroupName,Groupcode,GroupOwner,GroupCategoryID 
System Administrators,sysadmin,13456,100
Independence High Teachers,HS Teachers,,101
John Glenn Middle Teachers,MS Teachers,13458,102
Liberty Elementary Teachers,Elem Teachers,13559,103
1st Grade Teachers,1stgrade,,104
2nd Grade Teachers,2nsgrade,13561,105
3rd Grade Teachers,3rdgrade,13562,106
Guidance Department,guidance,,107

1) 그리고csvkit(CSV 변환 및 작업을 위한 명령줄 도구 세트)

수입하다SQLite3데이터 베이스:

csvsql --db sqlite:///test_db --tables test_tbl --insert test.csv

입력 csv 파일이 지정되지 않으면 stdin에서 csv 데이터를 허용합니다.

... | csvsql --db sqlite:///test_db --tables test_tbl --insert

데이터 추출SQLite데이터 베이스:

sql2csv --db sqlite:///test_db --query 'select * from test_tbl limit 3'

산출:

GroupName,Groupcode,GroupOwner,GroupCategoryID 
System Administrators,sysadmin,13456,100
Independence High Teachers,HS Teachers,,101
John Glenn Middle Teachers,MS Teachers,13458,102

2) 그리고SQLite3명령줄 도구(사용자가 SQL 문을 수동으로 입력하고 실행할 수 있음)SQLite데이터 베이스)

" .import" 명령을 사용하여 CSV(쉼표로 구분된 값) 데이터를 SQLite 테이블로 가져옵니다. " .import" 명령에는 두 개의 매개변수, 즉 CSV 데이터를 읽어올 디스크 파일 이름과 CSV 데이터를 삽입할 SQLite 테이블 이름이 있습니다.

" " 명령을 실행하기 전에 "모드"를 "csv"로 설정하는 것이 중요합니다 .import. 이는 명령줄 셸이 입력 파일 텍스트를 다른 형식으로 해석하는 것을 방지하는 데 필요합니다.

$ sqlite3
sqlite> .mode csv
sqlite> .import test.csv test_tbl
sqlite> select GroupName,Groupcode from test_tbl limit 5;
"System Administrators",sysadmin
"Independence High Teachers","HS Teachers"
"John Glenn Middle Teachers","MS Teachers"
"Liberty Elementary Teachers","Elem Teachers"
"1st Grade Teachers",1stgrade
sqlite> 

답변3

유닉스 계열 시스템에서는sqlite3주문하다.importCSV 내용은 특수 파일의 표준 입력에서 읽을 수 있습니다 /dev/stdin.

$ printf "col1,col2\na,1\nb,2\n" | sqlite3 test.db ".import --csv /dev/stdin test"
$ sqlite3 -csv -header test.db "SELECT * FROM test"
col1,col2
a,1
$ sqlite3 -version
3.32.3 2020-06-18 14:00:33 7ebdfa80be8e8e73324b8d66b3460222eb74c7e9dfd655b48d6ca7e1933cc8fd
b,2

답변4

다음 bash 함수는 csv_to_sqlite표준 입력에서 CSV 내용을 읽고 다음 명령을 사용하여 이를 SQLite 데이터베이스 테이블로 가져옵니다.sqlite3주문하다.import임시 명명된 파이프(FIFO):

#!/bin/bash

function csv_to_sqlite() {
  local database_file_name="$1"
  local table_name="$2"
  local temp_input_fifo=$(mktemp -u)
  mkfifo $temp_input_fifo
  sqlite3 -csv $database_file_name ".import $temp_input_fifo $table_name" &
  cat > $temp_input_fifo
  rm $temp_input_fifo
}

database_file_name=$1
table_name=$2

csv_to_sqlite "$database_file_name" "$table_name"
$ printf "col1,col2,col3\na,1,2.6\nb,2,5.4\n" | ./csv_to_sqlite test.sqlite test
$ sqlite3 -csv -header test.sqlite "SELECT * FROM test"
col1,col2,col3
a,1,2.6
b,2,5.4

관련 정보