๐ ngrok๋?
๐ ์์ฝ:
ngrok์ ๋ด ์ปดํจํฐ๋ ๋ด๋ถ๋ง์ ์๋ ์๋ฒ๋ฅผ ์ธ๋ถ์์ ์ ๊ทผํ ์ ์๊ฒ ํด์ฃผ๋ ๋๊ตฌ์.
๋ก์ปฌ์์ ๋์ด ์๋ฒ๋, ์ฌ์ค๋ง์ ์๋ DB ์๋ฒ ๋ฑ์ ์ธ๋ถ์์ ์ ๊ทผํ๊ณ ์ถ์ ๋
์์๋ก ๊ณต์ฉ ์ฃผ์(๋๋ฉ์ธ+ํฌํธ)๋ฅผ ๋ง๋ค์ด์ฃผ๋ ํฐ๋๋ง ์๋น์ค๋ผ๊ณ ๋ณด๋ฉด ๋จ.
โ ngrok์ ํต์ฌ ๊ฐ๋ ์ ๋ฆฌ
- ๋ก์ปฌ์ด๋ ๋ด๋ถ๋ง์์ ์คํ ์ค์ธ ์๋ฒ๋ฅผ ์ธ๋ถ์์ ์ ๊ทผํ ์ ์๋๋ก ์์ ๊ณต๊ฐ ์ฃผ์๋ฅผ ๋ง๋ค์ด์ฃผ๋ ๊ฒ์ด ngrok์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋ฅ์ด๋ค.
- ngrok์ ๊ฐ์ฅ ํต์ฌ ๊ธฐ๋ฅ์ public URL ↔ local server ์ฐ๊ฒฐ.
- ์ค์ ๋ก ngrok http 8000 ๋๋ ngrok tcp 1521 ๋ฑ์ ์คํํ๋ฉด ๊ณต๊ฐ ์ฃผ์๊ฐ ์์ฑ๋จ.
- ์ธ๋ถ์์ ์์ฒญ์ด ๋ค์ด์์ง๋ง ๋ฐฉํ๋ฒฝ์ด๋ NAT๋ก ์ธํด ์๋ต์ ์ ๋ฌํ ์ ์๋ ๊ฒฝ์ฐ, ngrok์ ๊ทธ ๋งํ ๊ฒฝ๋ก๋ฅผ ์ฐํํด์ ์๋ต์ ์ฃผ๊ณ ๋ฐ์ ์ ์๊ฒ ๋์์ค๋ค.
- ์ผ๋ฐ์ ์ผ๋ก ๋ก์ปฌ ์๋ฒ๋ ๊ณต์ธ IP๊ฐ ์๊ฑฐ๋ ํฌํธ๊ฐ ๋งํ ์์ด์ ์ธ๋ถ์์ ์ง์ ์ ๊ทผ ๋ถ๊ฐ๋ฅ.
- ngrok์ ์์ ์ ์๋ฒ(๊ณต์ธ IP)๋ฅผ ํตํด ์์ฒญ์ ๋ฐ๊ณ , ๋ด ์๋ฒ๋ก ํฐ๋๋งํด ์ ๋ฌํจ.
- ๋ด๋ถ ์๋ฒ์ ์ธ๋ถ ๋คํธ์ํฌ ์ฌ์ด์ ์์ ํ ํฐ๋์ ํ์ฑํด์ฃผ๋ ๊ฒ์ด ngrok์ ํต์ฌ ์ญํ ์ค ํ๋๋ค.
- ngrok์ TLS(์ํธํ๋ ์ฑ๋)๋ฅผ ํตํด ๋ณด์ ํฐ๋๋ง์ ์ ๊ณตํจ.
- ๋ด๋ถ์ ์ธ๋ถ ๊ฐ ํต์ ์ ์ํธํ๋ ์์ ํ ์ฐ๊ฒฐ๋ก ์ ์งํด์ค.
- ngrok์ ์ธ๋ถ ์์ฒญ์ ๋์ ๋ฐ์ ๋ด๋ถ ์๋ฒ์ ์ ๋ฌํ๊ณ , ๋ด๋ถ์ ์๋ต๋ ๋ค์ ์ธ๋ถ๋ก ์ ๋ฌํด์ฃผ๋ ์ผ์ข
์ ์ค๊ณ์ ๋๋ ๋๋ฆฌ ์๋ฒ์ฒ๋ผ ์๋ํ๋ค.
- ์ด๊ฒ ๋ฐ๋ก reverse proxy(์ญ๋ฐฉํฅ ํ๋ก์)์ ๊ฐ๋ ์.
- ngrok ์๋ฒ๊ฐ ์ค๊ณ ์๋ฒ ์ญํ ์ ํ๋ฉฐ, ์ธ๋ถ ์ฌ์ฉ์๋ ngrok ์๋ฒ๋ฅผ ํตํด ์ ์ํจ.
- ์น ์์ฒญ๋ฟ ์๋๋ผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์๊ณผ ๊ฐ์ TCP ์์ฒญ๋ ngrok์ ํตํด ์ธ๋ถ์์ ๋ด๋ถ๋ก ์์ ํ๊ฒ ์ ๋ฌํ ์ ์๋ค.
- ngrok์ http, tcp, tls ํ๋กํ ์ฝ์ ์ง์ํจ.
- TCP ํฌํธ(์: 1521, 3306)๋ ngrok tcp ํฌ์๋ฉ์ผ๋ก ์ธ๋ถ์ ๋ ธ์ถ ๊ฐ๋ฅ.
โ ์ธ์ ์ฌ์ฉํ๋๊ฐ?
- ๋ก์ปฌ ์น ์๋ฒ๋ API๋ฅผ ์ธ๋ถ ํ ์คํธ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ฃผ๊ณ ์ถ์ ๋
- ํด๋ผ์ฐ๋์ ๋ฐฐํฌํ์ง ์์ ์๋ฒ๋ฅผ ์ธ๋ถ์์ ์ ๊ทผํ๊ฒ ํ๊ณ ์ถ์ ๋
- ์ธ๋ถ DB (MySQL, Oracle ๋ฑ)์ ๋ก์ปฌ ํ๊ฒฝ์์ ์ ์ํ๊ณ ์ ํ ๋
- ์นํ (webhook), ์ฌ๋, ๊ฒฐ์ API ๊ฐ์ ์ธ๋ถ ์๋น์ค๊ฐ ๋ด ์๋ฒ๋ก ์ฝ๋ฐฑํ ๋
- ๋ก์ปฌ ๊ฐ๋ฐ ํ๊ฒฝ์ ํด๋ผ์ด์ธํธ์๊ฒ ์์๋ก ๊ณต์ ํ๊ณ ์ถ์ ๋
โ๏ธ ngrok ์คํ ํ๋ก์ธ์ค (CLI ๋ฒ์ )
๐ ๏ธ Step 1. ngrok ์ค์น ๋ฐ ๋ก๊ทธ์ธ
# ngrok ๊ณต์ ํ์ด์ง์์ ํ์๊ฐ์
ํ ํ ํฐ ๋ณต์ฌ
ngrok config add-authtoken YOUR_NGROK_TOKEN
๐ ๏ธ Step 2. ํฌํธ ์ด๊ธฐ. ํฌํธ ์ธ๋ถ ๊ฐ๋ฐฉ
ngrok tcp 1521 # ์: Oracle DB 1521 ํฌํธ ์ด๊ธฐ
ngrok http 8000 # ์: ๋ก์ปฌ ์น์๋ฒ 8000 ํฌํธ ์ด๊ธฐ
์คํํ๋ฉด ์๋์ฒ๋ผ ์์ ๋๋ฉ์ธ ์ฃผ์์ ํฌํธ๊ฐ ์์ฑ๋จ
๐ ๊ฒฐ๊ณผ ์์
Forwarding tcp://0.tcp.jp.ngrok.io:14190 → localhost:1521
์ด ์ฃผ์ 0.tcp.jp.ngrok.io:14190๊ฐ ๋ฐ๋ก ์ธ๋ถ์์ Oracle DB์ ์ ์ํ ์ ์๋ ์ฃผ์์.
Colab์์๋ ์ด ์ฃผ์๋ฅผ host, port์ ๋ฃ์ผ๋ฉด ๋จ. Oracle ์ฐ๊ฒฐ์์ host: 0.tcp.jp.ngrok.io, port: 14190๋ฅผ ์ฌ์ฉ.
๐ก Colab์์ ngrok ํ์ด์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์ฌ๋ ๋ฐฉ๋ฒ (pyngrok)
Colab์์ CLI ๋ณด๋ค ํธ๋ฆฌํ ๋ฐฉ์
โถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
!pip install pyngrok
โถ ngrok์ผ๋ก TCP ํฌํธ ์ด๊ธฐ
from pyngrok import ngrok
# ngrok ์ธ์ฆ ํ ํฐ ๋ฑ๋ก (ํ ๋ฒ๋ง)
ngrok.set_auth_token("YOUR_NGROK_TOKEN")
# Oracle์ด ๋ก์ปฌ์์ 1521 ํฌํธ๋ก ์ด๋ ค ์๋ค๊ณ ๊ฐ์
tcp_tunnel = ngrok.connect(1521, "tcp")
print(tcp_tunnel.public_url)
์ถ๋ ฅ ์์:
tcp://0.tcp.ngrok.io:14190
์ด๊ฑธ ๊ทธ๋๋ก Oracle ์ฐ๊ฒฐ ์ค์ ์ ์ฌ์ฉํ๋ฉด ๋จ.
๐งฉ create_engine()๋ ๋ฌด์จ ์ญํ ์ ํ๋๊ฐ?
SQLAlchemy์ create_engine()๋
Python ์ฝ๋์์ ์ธ๋ถ DB ์๋ฒ์ ์ฐ๊ฒฐ์ ์ค์ ํด์ฃผ๋ ํจ์์.
์ฆ, DB ์ฐ๊ฒฐ์ ์ํ ์ ์ ์ ๋ณด(์ ์ , ๋น๋ฐ๋ฒํธ, ํธ์คํธ, ํฌํธ, DB๋ช )์ ์ด์ฉํด์
Pandas์ SQL์ ์ฐ๊ฒฐํด์ฃผ๋ ๋ค๋ฆฌ ์ญํ ์ ํจ.
ํ ๋ฒ ์ฐ๊ฒฐ ๊ฐ์ฒด(engine)๋ฅผ ๋ง๋ค๋ฉด,
pd.read_sql()์ด๋ to_sql() ๊ฐ์ ๊ธฐ๋ฅ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ ๋กญ๊ฒ ์ฃผ๊ณ ๋ฐ์ ์ ์์.
๐ฆ Oracle → MySQL ๋ฐ์ดํฐ ์ด์ ์ฝ๋
1๏ธโฃ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
!pip install -U mysql-connector-python
!pip install -U pandas
!pip install -U sqlalchemy
!pip install -U oracledb
- ๊ฐ๊ฐ MySQL ์ฐ๊ฒฐ, ๋ฐ์ดํฐ ์ฒ๋ฆฌ, DB ์ฐ๋, Oracle ์ฐ๋์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น.
2๏ธโฃ Oracle ์ฐ๊ฒฐ ๋ฐ ์กฐํ
from sqlalchemy import create_engine
import pandas as pd
user = "oracle_user"
password = "oracle_pw"
host = "0.tcp.jp.ngrok.io"
port = '14190'
database = "oracle_db"
engine = create_engine(f'oracle+cx_oracle://{user}:{password}@{host}:{port}/{database}')
tableName = "EXAMPLE_TABLE"
query = f"SELECT * FROM {tableName}"
productData = pd.read_sql(query, con=engine)
โ ์ค๋ช :
- ngrok์ผ๋ก ์ด์ด๋ Oracle ์๋ฒ์ ์ฐ๊ฒฐ
- SQLAlchemy๋ฅผ ์ด์ฉํด์ Pandas์ ์ฐ๋
- ํ ์ด๋ธ์ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ productData๋ผ๋ DataFrame์ผ๋ก ๊ฐ์ ธ์ด
3๏ธโฃ MySQL ์ฐ๊ฒฐ ๋ฐ ์ ์ฅ
myuser = "mysql_user"
mypassword = "mysql_pw"
myhost = "my.mysql.host"
myport = '3306'
mydatabase = "mysql_db"
myengine = create_engine(f'mysql+mysqlconnector://{myuser}:{mypassword}@{myhost}:{myport}/{mydatabase}')
tableName = "MY_TARGET_TABLE"
productData.to_sql(name=tableName, con=myengine, if_exists="append", index=False)
โ ์ค๋ช :
- MySQL ์๋ฒ์ ์ฐ๊ฒฐ
- ์์์ Oracle์์ ๋ถ๋ฌ์จ productData๋ฅผ MySQL์ ํ ์ด๋ธ์ ์ ์ฅ
- if_exists="append" → ๊ธฐ์กด ํ ์ด๋ธ์ด ์๋ค๋ฉด ์ด์ด์ ์ถ๊ฐํจ (๋ฎ์ด์ฐ๊ธฐ ์๋)
- index=False → Pandas์ ์ธ๋ฑ์ค ์ปฌ๋ผ์ ์ ์ฅํ์ง ์์
โ ์ ์ฒด ํ๋ฆ ์์ฝ
- ngrok์ผ๋ก Oracle ํฌํธ๋ฅผ ์ธ๋ถ์ ์ด์ด๋ (tcp ํฌํธ ํฌ์๋ฉ)
- Oracle DB ํฌํธ์ ๋ํ public ์ฃผ์ ์์ฑ
- Colab์์ ํด๋น ์ฃผ์๋ฅผ ํตํด Oracle์ ์ ์
- ํ ์ด๋ธ ๋ฐ์ดํฐ๋ฅผ Pandas์ DataFrame ํํ๋ก ๋ถ๋ฌ์ด
- DataFrame์ผ๋ก ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ MySQL์ ์ ์ฅ (to_sql ์ฌ์ฉ)
- DataFrame์ ์ฌ์ฉํจ์ผ๋ก์จ ์ฌ๋ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ํตํฉํ๊ณ , ๊ฐ๊ณตํ๊ฑฐ๋ ๋ค๋ฅธ ํ์์ผ๋ก ๋ณํํด ์ ์ฅํ ์ ์์ด ์ ์ฐ์ฑ์ด ๋์
- Oracle (ngrok ๊ฐ๋ฐฉ) → Colab (Pandas DataFrame) → MySQL (to_sql ์ ์ฅ)
- Oracle ๊ฐ๋ฐฉ ์ค์ + ์ธ๋ถ ํ๊ฒฝ์์ DB ์ ์ + ๋ฐ์ดํฐ ์ด์ ๊น์ง๋ฅผ ์์ ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ์ค์ฉ์ ์ธ ๋ฐฉ์
โ ๋ง๋ฌด๋ฆฌ ์์ฝ
๊ตฌ๋ถ | ์ค๋ช |
ngrok | ๋ก์ปฌ/๋ด๋ถ๋ง ์๋ฒ๋ฅผ ์ธ๋ถ์์ ์ ๊ทผ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ ํฐ๋๋ง ๋๊ตฌ |
create_engine() | DB ์ ์ ์ ๋ณด๋ฅผ ์ด์ฉํด Python๊ณผ ์ธ๋ถ DB๋ฅผ ์ฐ๊ฒฐํ๋ ํจ์ |
์ฌ์ฉ ์ฌ๋ก | Oracle, MySQL, webhook ๋ฑ ์ธ๋ถ ์ฐ๋ ํ ์คํธ |
ํ์ด์ฌ ์คํ๋ฒ | pyngrok ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก Colab ๋ฑ์์ ngrok ์ ์ด ๊ฐ๋ฅ |
โ Oracle → MySQL ๋ฐ์ดํฐ ์ด์ ์ ์ฒด ํ๋ฆ ํจ์ํ ์์
from sqlalchemy import create_engine
import pandas as pd
def transfer_oracle_to_mysql(
oracle_config: dict,
mysql_config: dict,
table_name: str,
if_exists: str = "append"
):
"""
Oracle์์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํด MySQL๋ก ์ ์ฅํ๋ ํจ์
Parameters:
- oracle_config: ์ค๋ผํด ์ ์ ์ ๋ณด (user, password, host, port, database)
- mysql_config: MySQL ์ ์ ์ ๋ณด (user, password, host, port, database)
- table_name: ํ
์ด๋ธ ์ด๋ฆ (์กฐํ/์ ์ฅ์ ๋์ผ ์ฌ์ฉ)
- if_exists: 'replace', 'append', 'fail' ์ค ํ๋
"""
# ์ค๋ผํด ์ฐ๊ฒฐ ์์ง
oracle_url = f'oracle+cx_oracle://{oracle_config["user"]}:{oracle_config["password"]}@{oracle_config["host"]}:{oracle_config["port"]}/{oracle_config["database"]}'
oracle_engine = create_engine(oracle_url)
# ๋ฐ์ดํฐ ์กฐํ
query = f"SELECT * FROM {table_name}"
df = pd.read_sql(query, con=oracle_engine)
# MySQL ์ฐ๊ฒฐ ์์ง
mysql_url = f'mysql+mysqlconnector://{mysql_config["user"]}:{mysql_config["password"]}@{mysql_config["host"]}:{mysql_config["port"]}/{mysql_config["database"]}'
mysql_engine = create_engine(mysql_url)
# ๋ฐ์ดํฐ ์ ์ฅ
df.to_sql(name=table_name, con=mysql_engine, if_exists=if_exists, index=False)
print(f"{table_name} ํ
์ด๋ธ ๋ฐ์ดํฐ๋ฅผ MySQL์ ์ ์ฅ ์๋ฃ")
# โ
์ฌ์ฉ ์์
oracle_info = {
"user": "oracle_user",
"password": "oracle_pw",
"host": "0.tcp.jp.ngrok.io",
"port": "14190",
"database": "oracle_db"
}
mysql_info = {
"user": "mysql_user",
"password": "mysql_pw",
"host": "mysql.host.com",
"port": "3306",
"database": "mysql_db"
}
transfer_oracle_to_mysql(oracle_info, mysql_info, table_name="EXAMPLE_TABLE")
๐ก ํจ์ ํ์ฉ ํฌ์ธํธ
- if_exists="append" → ๊ธฐ์กด ํ ์ด๋ธ์ ์ด์ด์ ์ ์ฅ
- replace๋ก ๋ฐ๊พธ๋ฉด ํ ์ด๋ธ ๋ฎ์ด์
- Oracle์์ MySQL๋ก ๋ฐ์ดํฐ ์ด์ ์๋ํ์ ์ ํฉ
- ngrok ์ฃผ์๋ง ๋ฐ๊ฟ์ฃผ๋ฉด ์ด๋์๋ ์ ์ ๊ฐ๋ฅ
'Python' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[python] ๋ฐ์ดํฐ ์์ง - ์น ํฌ๋กค๋ง (0) | 2025.03.25 |
---|---|
[Colab] Colab & Jupyter์์ !, %, %% Magic commands ์๋ฒฝ ์ ๋ฆฌ (0) | 2025.03.24 |
[Python] Python ๋ชจ๋์ import ๋ฐ from import ์ ๋ฆฌ (0) | 2025.03.19 |
[python] ํ์ด์ฌ sequence ์๋ฃํ (0) | 2021.12.19 |
[python] ํ์ด์ฌ ์ซ์ ๊ฐ ์๋ฆฌ์ ๋ถ๋ฆฌ (0) | 2021.12.17 |
๋๊ธ