#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Explanation: Copyright 2020 The TensorFlow IO Authors.
End of explanation
"""


try:
  %tensorflow_version 2.x
except Exception:
  pass

!pip install tensorflow-io

"""
Explanation: TensorFlow IO에서 PostgreSQL 데이터베이스 읽기
<table class="tfo-notebook-buttons" align="left">
  <td><a target="_blank" href="https://www.tensorflow.org/io/tutorials/postgresql"><img src="https://www.tensorflow.org/images/tf_logo_32px.png">TensorFlow.org에서 보기</a></td>
  <td><a target="_blank" href="https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/ko/io/tutorials/postgresql.ipynb"><img src="https://www.tensorflow.org/images/colab_logo_32px.png">Google Colab에서 실행하기</a></td>
  <td><a target="_blank" href="https://github.com/tensorflow/docs-l10n/blob/master/site/ko/io/tutorials/postgresql.ipynb"><img src="https://www.tensorflow.org/images/GitHub-Mark-32px.png">GitHub에서소스 보기</a></td>
      <td><a href="https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/ko/io/tutorials/postgresql.ipynb"><img src="https://www.tensorflow.org/images/download_logo_32px.png">노트북 다운로드하기</a></td>
</table>

개요
이 튜토리얼에서는 PostgreSQL 데이터베이스 서버에서 tf.data.Dataset를 생성하는 방법을 보여줍니다. 생성된 Dataset를 훈련이나 추론 목적으로 tf.keras로 전달할 수 있습니다.
SQL 데이터베이스는 데이터 과학자에게 중요한 데이터 소스입니다. 가장 널리 사용되는 오픈 소스 SQL 데이터베이스 중 하나인 PostgreSQL은 기업에서 중요 데이터와 트랜잭션 데이터를 전사적으로 저장하는 데 보편적으로 사용됩니다. PostgreSQL 데이터베이스 서버에서 직접 Dataset를 만들고 훈련 또는 추론 목적으로 Dataset를 tf.keras로 전달하면 데이터 파이프라인이 크게 간소화되고 데이터 과학자들이 머신러닝 모델을 빌드하는 데 집중할 수 있습니다.
설정 및 사용법
필요한 tensorflow-io 패키지를 설치하고 런타임 다시 시작하기
End of explanation
"""


# Install postgresql server
!sudo apt-get -y -qq update
!sudo apt-get -y -qq install postgresql
!sudo service postgresql start

# Setup a password `postgres` for username `postgres`
!sudo -u postgres psql -U postgres -c "ALTER USER postgres PASSWORD 'postgres';"

# Setup a database with name `tfio_demo` to be used
!sudo -u postgres psql -U postgres -c 'DROP DATABASE IF EXISTS tfio_demo;'
!sudo -u postgres psql -U postgres -c 'CREATE DATABASE tfio_demo;'

"""
Explanation: PostgreSQL 설치 및 설정하기(선택 사항)
경고: 이 노트북은 Google Colab에서만 실행되도록 설계되었습니다. 여기서는 시스템에 패키지를 설치하고 sudo 액세스가 필요합니다. 로컬 Jupyter 노트북에서 실행하려면 주의해서 진행해야 합니다.
Google Colab에서 사용법을 데모하기 위해 PostgreSQL 서버를 설치합니다. 암호와 빈 데이터베이스도 필요합니다.
Google Colab에서 이 노트북을 실행하지 않거나 기존 데이터베이스를 사용하려는 경우 다음 설정을 건너뛰고 다음 섹션으로 진행하세요.
End of explanation
"""


%env TFIO_DEMO_DATABASE_NAME=tfio_demo
%env TFIO_DEMO_DATABASE_HOST=localhost
%env TFIO_DEMO_DATABASE_PORT=5432
%env TFIO_DEMO_DATABASE_USER=postgres
%env TFIO_DEMO_DATABASE_PASS=postgres

"""
Explanation: 필요한 환경 변수 설정하기
다음 환경 변수는 마지막 섹션의 PostgreSQL 설정을 기반으로 합니다. 다른 설정이 있거나 기존 데이터베이스를 사용하는 경우 적절하게 변경해야 합니다.
End of explanation
"""


!curl -s -OL https://github.com/tensorflow/io/raw/master/docs/tutorials/postgresql/AirQualityUCI.sql

!PGPASSWORD=$TFIO_DEMO_DATABASE_PASS psql -q -h $TFIO_DEMO_DATABASE_HOST -p $TFIO_DEMO_DATABASE_PORT -U $TFIO_DEMO_DATABASE_USER -d $TFIO_DEMO_DATABASE_NAME -f AirQualityUCI.sql

"""
Explanation: PostgreSQL 서버에서 데이터 준비하기
이 튜토리얼에서는 데모 목적으로 데이터베이스를 생성하고 데이터베이스에 일부 데이터를 채웁니다. 이 가이드에 사용된 데이터는 UCI 머신러닝 리포지토리에서 제공되는 대기 품질 데이터세트에서 가져온 것입니다.
다음은 대기 질 데이터세트의 일부를 미리 나타낸 것입니다.
날짜 | 시간 | CO (GT) | PT08.S1 (CO) | NMHC (GT) | C6H6 (GT) | PT08.S2 (NMHC) | NOx (GT) | PT08.S3 (NOx) | NO2 (GT) | PT08.S4 (NO2) | PT08.S5 (O3) | 티 | RH | AH
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
10/03/2004 | 18.00.00 | 2,6 | 1360 | 150 | 11,9 | 1046 | 166 | 1056 | 113 | 1692 년 | 1268 년 | 13,6 | 48,9 | 0,7578
10/03/2004 | 19.00.00 | 2 | 1292 | 112 | 9,4 | 955 | 103 | 1174 년 | 92 | 1559 년 | 972 | 13,3 | 47,7 | 0,7255
10/03/2004 | 20.00.00 | 2,2 | 1402 | 88 | 9,0 | 939 | 131 | 1140 년 | 114 | 1555 년 | 1074 | 11,9 | 54,0 | 0,7502
10/03/2004 | 21.00.00 | 2,2 | 1376 | 80 | 9,2 | 948 | 172 | 1092 | 122 | 1584 년 | 1203 년 | 11,0 | 60,0 | 0,7867
10/03/2004 | 22.00.00 | 1,6 | 1272 | 51 | 6,5 | 836 | 131 | 1205 년 | 116 | 1490 | 1110 년 | 11,2 | 59,6 | 0,7888
대기 품질 데이터세트 및 UCI 머신러닝 리포지토리에 대한 자세한 정보는 참고 문헌 섹션에서 확인할 수 있습니다.
데이터 준비를 단순화하기 위해 대기 품질 데이터세트의 SQL 버전이 준비되었으며 AirQualityUCI.sql로 제공됩니다.
테이블을 만드는 문은 다음과 같습니다.
CREATE TABLE AirQualityUCI (
  Date DATE,
  Time TIME,
  CO REAL,
  PT08S1 INT,
  NMHC REAL,
  C6H6 REAL,
  PT08S2 INT,
  NOx REAL,
  PT08S3 INT,
  NO2 REAL,
  PT08S4 INT,
  PT08S5 INT,
  T REAL,
  RH REAL,
  AH REAL
);
데이터베이스에 테이블을 만들고 데이터를 채우는 전체 명령은 다음과 같습니다.
End of explanation
"""


import os
import tensorflow_io as tfio

endpoint="postgresql://{}:{}@{}?port={}&dbname={}".format(
    os.environ['TFIO_DEMO_DATABASE_USER'],
    os.environ['TFIO_DEMO_DATABASE_PASS'],
    os.environ['TFIO_DEMO_DATABASE_HOST'],
    os.environ['TFIO_DEMO_DATABASE_PORT'],
    os.environ['TFIO_DEMO_DATABASE_NAME'],
)

dataset = tfio.experimental.IODataset.from_sql(
    query="SELECT co, pt08s1 FROM AirQualityUCI;",
    endpoint=endpoint)

print(dataset.element_spec)

"""
Explanation: PostgreSQL 서버에서 데이터세트를 만들고 TensorFlow에서 사용하기
PostgreSQL 서버에서 데이터세트를 만들려면 query 및 endpoint 인수를 사용하여 tfio.experimental.IODataset.from_sql을 호출하기만 하면 됩니다. query는 테이블의 선택 열에 대한 SQL 쿼리이고 endpoint 인수는 주소 및 데이터베이스 이름입니다.
End of explanation
"""


dataset = tfio.experimental.IODataset.from_sql(
    query="SELECT nox, no2 FROM AirQualityUCI;",
    endpoint=endpoint)

dataset = dataset.map(lambda e: (e['nox'] - e['no2']))

# check only the first 20 record
dataset = dataset.take(20)

print("NOx - NO2:")
for difference in dataset:
  print(difference.numpy())

"""
Explanation: 위의 dataset.element_spec 출력에서 알 수 있듯이 생성된 Dataset의 요소는 데이터베이스 테이블의 열 이름을 키로 사용하는 python dict 개체입니다. 추가 작업을 적용하면 매우 편리합니다. 예를 들어 Dataset의 nox 및 no2 필드를 모두 선택하고 차이를 계산할 수 있습니다.
End of explanation
"""


