Skip to content

Commit

Permalink
update etl and duckdb
Browse files Browse the repository at this point in the history
  • Loading branch information
statkclee committed Jan 30, 2024
1 parent 66061e6 commit 3bab6ad
Show file tree
Hide file tree
Showing 16 changed files with 1,738 additions and 785 deletions.
551 changes: 266 additions & 285 deletions docs/duck_postgreSQL.html

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
517 changes: 259 additions & 258 deletions docs/etl.html

Large diffs are not rendered by default.

Binary file added docs/images/chicago_crime_type.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/survey_collect_gg.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
751 changes: 743 additions & 8 deletions docs/index.html

Large diffs are not rendered by default.

57 changes: 39 additions & 18 deletions docs/search.json

Large diffs are not rendered by default.

56 changes: 41 additions & 15 deletions docs/setup.html

Large diffs are not rendered by default.

454 changes: 289 additions & 165 deletions duck_postgreSQL.qmd

Large diffs are not rendered by default.

97 changes: 62 additions & 35 deletions etl.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ ETL은 데이터베이스에서 데이터를 처리하는 세 단계, 즉 'Extra
윈도우에서 파이썬으로 CSV 파일을 읽어드리게 되면 인코딩 오류가 발생하는 경우가 있다.
이를 방지하기 위해 인코딩을 `UTF-8`으로 설정한다.

```{{python}}
```{python}
#| eval: false
# count-lines.py
# 스프레드쉬트에 얼마나 많은 줄이 있는지 계수한다.
# -*- coding: utf-8 -*-
import sys
filename = sys.argv[1]
Expand Down Expand Up @@ -70,12 +69,11 @@ $ python code/count-lines.py data/bibliography.csv
라이브러리 문서에 일부 예제가 포함되어 있다.
몇번 실험을 한 뒤에, 다음과 같은 결과가 나오게 된다:

```{{python}}
```{python}
#| eval: false
# read-fields.py
# CSV 파일에서 필드값을 제대로 읽어 오는지 확인한다.
# -*- coding: utf-8 -*-
import sys
import csv
Expand Down Expand Up @@ -108,12 +106,11 @@ $ python code/read-fields.py data/bibliography.csv | head -5
(프로그램 출력결과를 `head` 명령어로 실행해서 출력결과를 스크롤해서 다시 위로 올라가기 보다 첫 몇줄만 화면에 출력함에 주목한다.) 상기 결과는 정확하게 필요한 결과다: 키값이 각 리스트 첫번째 구성요소로 있고, 저자는 모두 네번째에 몰려있따.
프로그램을 변경해서, 단지 두 필드만 출력하게 변경하자:

```{{python}}
```{python}
#| eval: false
# display-fields.py
# 키값과 저자 모두를 화면에 출력한다.
# -*- coding: utf-8 -*-
import sys
import csv
Expand Down Expand Up @@ -160,12 +157,12 @@ PNGQMCP5 Niculescu-Mizil, Alexandru
하지만, 꼭 그렇지는 않다; 저자명은 실제로 세미콜론과 공백으로 구분되는데 세미콜론만으로 구분했기 때문에, 각 줄마다 두번째와 이어진 명칭에 원치않는 공백이 앞에 온다.
세미콜론과 공백으로 쪼개면 어떻게 될까?

```{{python}}
```{python}
#| eval: false
# display-authors-2.py
# (키값, 저자명) 짝을 화면에 출력한다.
# -*- coding: utf-8 -*-
import sys
import csv
Expand Down Expand Up @@ -196,6 +193,8 @@ PNGQMCP5 Caruana, Rich
PNGQMCP5 Niculescu-Mizil, Alexandru
```
:::{.callout-note}
### 버전 관리
이로써 데이터 추출의 첫 번째 단계가 완료되어, 재사용 가능한 유용한 코드를 얻었기 때문에, 후속 작업을 위해서 저장한다. 깃(Git) 버전 제어는 데이터 처리 및 분석의 복잡성과 변화에 대응하는 데 있어 핵심적인 역할을 한다. ETL 과정은 데이터의 추출, 변환 및 로드 과정에서 수많은 쿼리와 스크립트를 포함하며, 이러한 작업들은 지속적으로 수정 및 개선이 필요하다. Git을 사용하면 이러한 변경사항을 효과적으로 추적하고 관리할 수 있다. 오류 발생시 이전 버전으로 쉽게 되돌릴 수 있게 해주며, 팀원 간의 협업에서도 변경 사항을 쉽게 공유하고 통합할 수 있게 한다. 또한, Git은 작업의 히스토리를 기록하여 프로젝트의 진행 상황을 명확하게 파악할 수 있도록 해주어 프로젝트 관리에도 큰 도움이 된다.
Expand Down Expand Up @@ -236,6 +235,8 @@ $ git commit -m "Extracting (key, author) pairs from bibliography"
create mode 100644 data/bibliography.csv
```
:::
## 자료 변환
**정규화(normalization)**는 데이터를 여러 테이블로 분할하는 과정으로
Expand All @@ -252,12 +253,12 @@ $ git commit -m "Extracting (key, author) pairs from bibliography"
데이터가 데이터베이스에 입력되면, 쿼리를 전송해서 질의 응답을 할 수 있다.
시작점으로 이전 학습과정에서 나온 최종 스크립트를 바탕으로 시작해보자.
```{{python}}
```{python}
#| eval: false
# display-authors-2.py
# (키값, 저자명) 짝을 화면에 출력한다.
# -*- coding: utf-8 -*-
import sys
import csv
Expand Down Expand Up @@ -292,12 +293,12 @@ PNGQMCP5 Niculescu-Mizil, Alexandru

데이터베이스에 넣을 수 있는 CSV 파일을 생성해보자.

```{{python}}
```{python}
#| eval: false
# convert-1.py
# 데이터베이스에 로드할 수 있는 CSV로 출력결과 전송
# -*- coding: utf-8 -*-
import sys
import csv
Expand Down Expand Up @@ -350,13 +351,15 @@ PNGQMCP5,"Caruana, Rich"
:::


## 적재 (Load)
## 자료 적재

이제 데이터를 적재하기 위해 스크립트를 만들어 `load_bibliography.sql` 파일을 호출한다.
이제 데이터를 적재(Load)하기 위해 스크립트를 만들어 `load_bibliography.sql` 파일을 호출한다.
`key_author.csv` 파일이 현재 작업디렉토리 아래 `data` 폴더 아래 저장되어 있기 대문에
다음과 같이 SQL 코드를 작성한다.

```{{sql}}
```{sql}
#| eval: false
# load_bibliography.sql
.mode csv
.import key_author.csv key_author
Expand Down Expand Up @@ -409,7 +412,9 @@ sqlite> .quit
먼저, 가장 활발히 논문을 저술한 저자를 찾아보자.
SQL 쿼리문을 작성해서 가장 빈도수가 높은 저자를 찾아 상위 10명을 추려보자.
```{{sql}}
```{sql}
#| eval: false
sqlite> SELECT author, count(*)
...> FROM key_author
...> GROUP BY author
Expand Down Expand Up @@ -454,7 +459,9 @@ Frasconi, P. 25
파이썬 데이터 전처리 단계의 일부로 이름을 정규화하고 데이터를 정제하는 작업은 별도로 하지 않고, 다른 질문에 답할 수 있는지 살펴봅시다. 먼저, 공저자로 가장 많이 참여한 저자를 찾아보자.
```{{sql}}
```{sql}
#| eval: false
SELECT a.author, b.author
FROM key_author a
JOIN key_author b USING(key)
Expand All @@ -480,7 +487,9 @@ Sironi, Amos Fua, Pascal
(`a.author > b.author`를 사용하여 각기 다른 저자 쌍이 한 번만 나타나도록 한다.)
만약 다른 저자들이 얼마나 자주 함께 작업했는지 알고 싶다면 어떻게 해야 할까?
```{{sql}}
```{sql}
#| eval: false
SELECT a.author, b.author, count(*)
FROM key_author a
JOIN key_author b USING(key)
Expand Down Expand Up @@ -569,18 +578,21 @@ key_author %>%
CSV 파일에서 행을 데이터베이스 레코드로 SQL `INSERT` 문장 통해 삽입한다.
먼저, SQL `INSERT` 코드를 다음과 같이 작성한다.
``` sql
```{sql}
#| eval: false
INSERT INTO data VALUES ('8SW85SQM', 'McClelland, James L');
INSERT INTO data VALUES ('85QV9X5F', 'McClelland, J. L.');
INSERT INTO data VALUES ('85QV9X5F', 'McNaughton, B. L.');
```
그래서, 대신에 상기 데이터를 출력하도록 프로그램을 변경하자:
```{{python}}
```{python}
#| eval: false
# convert-1.py
# 데이터베이스에 (키값, 저자명) 짝을 집어넣는 SQL 문장을 생성한다.
# -*- coding: utf-8 -*-
import sys
import csv
Expand Down Expand Up @@ -611,14 +623,18 @@ raw.close()
첫번째 문제는 풀기 쉽다. 프로그램 시작부분에 다음 코드를 추가한다.
``` sql
```{sql}
#| eval: false
CREATE = 'CREATE TABLE data(key text not null, author text not null);'
```
어떤 `insert` 문장을 출력하기 전에 출력한다.
두번째 문제는 더 까다롭다: 만약 "O'Mear, Fiona" 같은 저자명을 `INSERT`해서 끼워넣으려면, 결과가 다음과 같이 된다:
``` sql
```{sql}
#| eval: false
"INSERT INTO data VALUES('RJS8QDC4', 'O'Mear, Fiona');"
```
Expand All @@ -627,10 +643,11 @@ CREATE = 'CREATE TABLE data(key text not null, author text not null);'
왜냐하면 사람 이름에 이중 인용부호는 포함될 수 없기 때문이다.
변경사항을 마치고 나면, 전체 프로그램은 다음과 같다:
```{{python}}
```{python}
#| eval: false
# convert-2.py
# 키값과 저자명에 대한 데이터베이스 생성.
# -*- coding: utf-8 -*-
import sys
import csv
Expand Down Expand Up @@ -679,6 +696,7 @@ sqlite> .schema
CREATE TABLE data(key text not null, author text not null);
sqlite> SELECT * FROM data LIMIT 10;
8SW85SQM|McClelland, James L
85QV9X5F|McClelland, J. L.
85QV9X5F|McNaughton, B. L.
Expand All @@ -694,13 +712,17 @@ PNGQMCP5|Niculescu-Mizil, Alexandru
결과가 좋아보인다.
그래서, 질의를 던져보자:
``` sql
```{sql}
#| eval: false
SELECT author, COUNT(*)
FROM data
GROUP BY author
ORDER BY COUNT(*) DESC
LIMIT 10;
```
``` bash
Bengio, Yoshua|122
Bengio, Y.|111
Hinton, Geoffrey E.|78
Expand All @@ -722,13 +744,15 @@ Frasconi, P.|25
저자명을 정규화하는 대신에, 대답할 수 있는 다른 질문을 살펴보자.
누가 누구와 공동으로 논문을 썼을까?
``` sql
```{sql}
#| eval: false
SELECT a.author, b.author
FROM data a
JOIN data b ON a.key = b.key AND a.author > b.author
LIMIT 10;
```
``` bash
McNaughton, B. L.|McClelland, J. L.
O'Reilly, R. C.|McClelland, J. L.
O'Reilly, R. C.|McNaughton, B. L.
Expand All @@ -743,14 +767,17 @@ Sironi, Amos|Fua, Pascal
(`a.author > b.author` 을 사용하게 되면, 완전히 다른 저자명 짝이 한번만 나오게 한다.) 다른 저자 짝이 얼마나 자주 함께 논문을 작성했는지 알고자 한다면 어떨까?
``` sql
```{sql}
#| eval: false
select a.author, b.author, count(*)
from data a join data b
on a.key=b.key and a.author > b.author
group by a.author, b.author
order by count(*) desc
limit 10;
```
``` bash
Vincent, Pascal|Bengio, Yoshua|27
Roux, Nicolas Le|Bengio, Yoshua|20
Delalleau, Olivier|Bengio, Yoshua|19
Expand Down
Binary file added etl_files/figure-html/convert-to-dataframe-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added etl_files/figure-html/unnamed-chunk-4-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/chicago_crime_type.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/survey_collect_gg.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 39 additions & 1 deletion setup.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ sqldiff.exe sqlite3_analyzer.exe

## 데이터베이스 설치

SQLite3를 설치했다면, 이제 데이터베이스(database)를 설치해야 한다. 데이터베이스는 테이블(table)과 뷰(view) 등의 객체가 포함된 파일이다. SQLite3는 데이터베이스를 생성할 때, 확장자를 지정하지 않는다. 데이터베이스 파일의 이름만 지정해도 되지만, 일반적으로 `.db`, `.sqlite`, `.sqlite3` 등 확장자를 사용하여 데이터베이스 파일임을 명확히 하는 것을 권장한다.
SQLite3를 설치했다면, 이제 데이터베이스(database)를 설치해야 한다. 데이터베이스는 테이블(table)과 뷰(view) 등의 객체가 포함된 파일이다. SQLite3는 데이터베이스를 생성할 때, 확장자를 지정하지 않는다. 데이터베이스 파일의 이름만 지정해도 되지만, 일반적으로 `.db`, `.sqlite`, `.sqlite3` 등 확장자를 사용하여 데이터베이스 파일임을 명확히 하는 것을 권장한다. [^duck_postgresql-1]

[^duck_postgresql-1]: [SQLite3 설치 및 간단한 사용법](http://blog.simplism.kr/?p=2329)


### `survey.db` 생성

Expand Down Expand Up @@ -138,6 +141,41 @@ Saving to: ‘gen-survey-database.sql’
$ sqlite3 survey.db < gen-survey-database.sql
```

### DB 연결/설치 점검 {#connect-sqlite}

생성된 데이터베이스에 연결하기 위해서, 데이터베이스를 생성한 디렉토리 안에서 SQLite를 시작한다.

```bash
$ sqlite3 survey.db
```

`sqlite3 survey.db` 명령문이 데이터베이스를 열고 데이터베이스 명령-라인 프롬프트로 안내한다.
SQLite에서 데이터베이스는 플랫 파일(flat file)로 명시적으로 열 필요가 있다.
그리고 나서 SQLite 시작되고 `sqlite`로 명령-라인 프롬프트가 다음과 같이 변경되어 표시된다.

```bash
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>
```

다음 출력결과가 보여주듯이 `.databases` 명령문으로 소속된 데이터베이스 이름과 파일 목록을 확인한다.

```bash
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main ~/novice/sql/survey.db
```

다음과 같이 타이핑해서 필요한 "Person", "Survey", "Site" "Visited" 테이블이 존재하는 것을 확인한다. `.table`의 출력결과는 다음과 같다.

```bash
sqlite> .tables
Person Site Survey Visited
```


## DB 브라우저
Expand Down

0 comments on commit 3bab6ad

Please sign in to comment.