μ΄λ² ν¬μ€ν κ³Ό λ€μ ν¬μ€ν μ ν΅ν΄ κ³΅ν΅ μμ€ν μμλΆν° λλ κ³΅ν΅ μμ€ν μΌλ‘
λ°μ΄ν°λ₯Ό λ΄λ³΄λ΄κ³ μμ§νκΈ° μν μ½λ μμ λ₯Ό μ΄μ©ν΄ 곡λΆλ₯Ό ν΄λ³΄κ² μ΄λ€..!
νμ΄μ¬ νκ²½ μ€μ
μμΌλ‘ λμ¬ λͺ¨λ μ½λ μμ λ νμ΄μ¬κ³Ό SQLλ‘ μμ±λλ©° μ€λλ λ°μ΄ν° μμ§λμ΄λ§ λΆμΌμμ νν μ¬μ©λλ μ€ν μμ€ νλ μμν¬λ₯Ό μ¬μ©νλ€
μ΄λ² μ€μ΅μ μ¬μ©λ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ€μΉνκΈ° μ μ μ€μΉν κ°μ νκ²½μ λ§λλ κ²μ΄ μ’λ€
=> λ€μν νλ‘μ νΈ λ° μ ν리μΌμ΄μ μ νμ΄μ¬ λΌμ΄λΈλ¬λ¦¬λ₯Ό κ΄λ¦¬νλλ° μ μ©ν virtualenv λꡬλ₯Ό μ¬μ©
(μ΄λ₯Ό ν΅ν΄ νμ΄μ¬ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ μμ΄ μλ νλ‘μ νΈμ λ§λ λ²μ λ΄μμ μ€μΉν μ μμ)
$ python -m venv env
λ₯Ό ν΅ν΄ envλΌλ κ°μ νκ²½μ μμ±νκ³
windowμ κ²½μ°
(μ κ° window νκ²½μμ μ€μ΅μ μ§νμ€..)
call env/scripts/activate
λ₯Ό ν΅ν΄ κ°μ νκ²½μ νμ±
μ¬μ§μ²λΌ κ°μ νκ²½μ΄ νμ±νλ¨
κ²°λ‘ : Scripts νμΌ μμ μλ activate.batμ μ€νμμΌ κ°μ νκ²½μ νμ±νν΄μ€λ€
μ΄λ κ² νλ©΄ μ½λ μμ μ νμν λΌμ΄λΈλ¬λ¦¬λ₯Ό μμ νκ² μ€μΉν μ μκ²λλ€!
=> pipμ μ¬μ©νμ¬ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ€μΉνλλ° pipλ λλΆλΆ νμ΄μ¬ λ°°ν¬μ ν¨κ» μ 곡λλ λꡬμ΄λ€
(env) pip install configparser
νμΌμ μΆκ°ν κ΅¬μ± μ 보λ₯Ό μ½λ λ° μ¬μ©λλ configparser λΌμ΄λΈλ¬λ¦¬λ₯Ό pipλ₯Ό μ¬μ©νμ¬ μ€μΉνλ€
κ·Έλ¦¬κ³ λμ€μ λ§λ€ νμ΄μ¬ μ€ν¬λ¦½νΈμ λμΌν λλ ν°λ¦¬μ pipeline.conf νμΌμ λ§λ λ€
(μΌλ¨ νμΌμ λΉμλ => λμ€μ μ½λ μμ λ‘ μ½λ μΆκ°ν μμ )
ν΄λΌμ°λ νμΌ μ€ν λ¦¬μ§ μ€μ
μ΄λ² μ€μ΅μμ νμΌ μ μ₯μ Amazon Simple Storage Service(Amazon S3) λ²ν·μ μ¬μ©νλ€
=> S3 λ²ν·μ λν μ μ ν μμΈμ€ μ μ΄ μ€μ μ μ¬μ© μ€μΈ λ°μ΄ν° μ¨μ΄νμ°μ€μ λ°λΌ λ¬λΌμ§
(μΌλ°μ μΌλ‘ μμΈμ€ κ΄λ¦¬ μ μ± μλ AWS Identitiy and Access Management(IAM) μν μ μ¬μ©νλ κ²μ΄ κ°μ₯ μ’μ)
κ° μΆμΆ μμ μμλ μ§μ λ μμ€ μμ€ν μμ λ°μ΄ν°λ₯Ό μΆμΆνκ³ μΆλ ₯μ S3 λ²ν·μ μ μ₯νλ€
(λ€μ ν¬μ€ν μ΄λ λ‘λ μμ λ ν΄λΉ λ°μ΄ν°λ₯Ό S3λ²ν·μμ λμμΌλ‘ λ‘λνλ€)
=> μ΄κ²μ΄ λ°μ΄ν° νμ΄νλΌμΈμ μΌλ°μ μΈ ν¨ν΄!
λ‘컬 λλ μ¨νλ λ―Έμ€ μ€ν 리μ§λ₯Ό μ¬μ©νλλ‘ κ° μμ λ₯Ό μμ ν μλ μμ§λ§
νΉμ ν΄λΌμ°λ μ 곡μ 체 μΈλΆμ μ€ν 리μ§μμ λ°μ΄ν° μ¨μ΄νμ°μ€λ‘ λ°μ΄ν°λ₯Ό λ‘λνλ €λ©΄
μΆκ° μμ μ΄ νμν μ μμ!
S3 λ²ν·κ³Ό μνΈ μμ©νκΈ° μν΄ μ€μΉν΄μΌ νλ νμ΄μ¬ λΌμ΄λΈλ¬λ¦¬κ° νλ λ μλ€
pip install boto3
=> νμ΄μ¬μ© AWS SDKμΈ Boto3
S3 λ²ν·κ³Ό μνΈ μμ©νκΈ° μν΄ Boto3 νμ΄μ¬ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νκΈ° λλ¬Έμ IAM μ¬μ©μλ₯Ό μμ±νκ³ ν΄λΉ μ¬μ©μμ λν μμΈμ€ ν€λ₯Ό μμ±νκ³ νμ΄μ¬ μ€ν¬λ¦½νΈμμ μ¬μ©ν μ μλ κ΅¬μ± νμΌμ ν€λ₯Ό μ μ₯ν΄μΌν¨
(μ€ν¬λ¦½νΈκ° S3 λ²ν·μ νμΌμ μ½κ³ μΈ μ μλ κΆνμ κ°λλ‘ νλ λ° λͺ¨λ νμν¨)
λ¨Όμ IAM μ¬μ©μλ₯Ό μμ±ν΄λ³΄μ
IAM -> μ¬μ©μλ₯Ό ν΄λ¦νλ€ [μ¬μ©μμμ±]μ λλ¬μ 'data_pipeline_readwrite'λ‘ μ΄λ¦μ μ§μ νλ€
νλ‘κ·Έλ¨ λ°©μ μ‘μΈμ€λ₯Ό μν΄ Consoleμ λν μ¬μ©μ μμΈμ€ κΆν μ 곡μ μλ [IAM μ¬μ©μλ₯Ό μμ±νκ³ μΆμ] μ μ ν!
λ€μμ λλ¬ κΆν μ€μ μμ μ§μ μ μ± μ°κ²°μ μ νν ν S3FullAccessλ₯Ό μ νν΄μ€λ€
μ΄λ κ² μμ±μ ν ν 보μ μ격 μ¦λͺ μ λ€μ΄κ°μ μ‘μΈμ€ ν€λ₯Ό μμ±νκ³ csv λ€μ΄λ‘λλ₯Ό ν΄λ¦
=> acces keyμ secret keyλ₯Ό μ μ μμ
=> bucket_nameμ S3 λ²ν·μ μμ±νκ³ ν΄λΉ λ²ν·μ μ΄λ¦μ λ£μ΄μ£Όκ³ νμ΄μ§ μ€λ₯Έμͺ½ μλ¨μ μλ κ³μ μ΄λ¦μ ν΄λ¦νμ¬ AWS κ³μ IDλ₯Ό account_idμ μ λ ₯ν΄μ€
MySQL λ°μ΄ν°λ² μ΄μ€μμ λ°μ΄ν° μΆμΆ
MySQL λ°μ΄ν°λ² μ΄μ€μμ λ°μ΄ν° μΆμΆμ
1. SQLμ μ¬μ©ν μ 체 λλ μ¦λΆ μΆμΆ
2. μ΄μ§ λ‘κ·Έ(binlog) 볡μ
λ°©λ²μ΄ μλ€
SQLμ μ¬μ©ν μ 체 λλ μ¦λΆ μΆμΆμ ꡬννκΈ° ν¨μ¬ κ°λ¨νμ§λ§
μμ£Ό λ³κ²½λλ λκ·λͺ¨ λ°μ΄ν°μ μμλ νμ₯μ±μ΄ λ¨μ΄μ§
μ΄μ§ λ‘κ·Έ 볡μ λ ꡬνμ΄ λ 볡μ‘νμ§λ§ μλ³Έ ν μ΄λΈμ λ³κ²½λλ λ°μ΄ν° λ³Όλ₯¨μ΄ ν¬κ±°λ MySQL μμ€μμ λ°μ΄ν°λ₯Ό λ μμ£Ό μμ§ν΄μΌ νλ κ²½μ°μ λ μ ν©ν¨
=> μ΄μ§ λ‘κ·Έ 볡μ λ μ€νΈλ¦¬λ° λ°μ΄ν° μμ§μ μννλ νλμ κ²½λ‘μ΄κΈ°λ ν¨
μ μ¬μ§ μ²λΌ MySQL λ°μ΄ν°λ² μ΄μ€μ Orders ν μ΄λΈμ λ§λ€κ³ νμ λͺκ° μ½μ νλ€
μ 체 λλ μ¦λΆ MySQL ν μ΄λΈ μΆμΆ
MySQL ν μ΄λΈμμ μ 체 λλ μΌλΆ μ΄μ λ°μ΄ν° μ¨μ΄νμ°μ€ λλ λ°μ΄ν° λ μ΄ν¬λ‘ μμ§ν΄μΌ νλ κ²½μ° μ 체 μΆμΆ λλ μ¦λΆ μΆμΆμ μ¬μ©νμ¬ μμ§ν μ μλ€
μ 체 μΆμΆμμλ μΆμΆ μμ μ μ€νν λλ§λ€ ν μ΄λΈμ λͺ¨λ λ μ½λκ° μΆμΆλλ€
=> κ°μ₯ λ 볡μ‘ν μ κ·Ό λ°©μμ΄μ§λ§ λμ©λ ν μ΄λΈμ κ²½μ° μ€ννλ λ° μ€λ μκ°μ΄ 걸릴 μ μλ€
SELECT *
FROM Orders;
μ¦λΆ μΆμΆμμλ μΆμΆ μμ μ λ§μ§λ§ μ€ν μ΄ν λ³κ²½λκ±°λ μΆκ°λ μλ³Έ ν μ΄λΈμ λ μ½λλ§ μΆμΆλλ€
λ§μ§λ§ μΆμΆμ νμμ€ν¬νλ
1. λ°μ΄ν° μ¨μ΄νμ°μ€μ μΆμΆ μμ λ‘κ·Έ ν μ΄λΈμ μ μ₯
2. μ¨μ΄νμ°μ€μ λμ ν μ΄λΈμμ λ§μ§λ§ μ λ°μ΄νΈ μ΄μ μ΅λ νμμ€ν¬νλ₯Ό 쿼리
νμ¬ κ²μν μ μλ€
SELECT *
FROM Orders
WHERE LastUpdated > {{ last_extraction_run }};
=> last_extraction_run λ³μλ μΆμΆ μμ μ μ΅κ·Ό μ€ν μκ°μ λνλ΄λ νμμ€ν¬νμ΄λ€!
(μΌλ°μ μΌλ‘ λ°μ΄ν° μ¨μ΄νμ°μ€μ λμ ν μ΄λΈμμ 쿼리λ¨)
SELECT MAX(LastUpdated)
FROM warehouse.Orders;
=> λ°μ΄ν° μ¨μ΄νμ°μ€μμ last_extraction_runμ μ¬μ©λ κ²°κ΄κ°μ νμΈν¨
λ³κ²½ν μ μλ λ°μ΄ν°(λ μ½λλ₯Ό μ½μ ν μλ μμ§λ§ μ λ°μ΄νΈν μλ μμ)κ° ν¬ν¨λ ν μ΄λΈμ κ²½μ°μλ LastUpdated μ΄ λμ λ μ½λκ° μμ±λ μκ°μ λν νμμ€ν¬νλ₯Ό μ¬μ©ν μ μλ€
Orders ν μ΄λΈμ΄ μλΉν ν° κ²½μ° λ€μ μΆμΆ μμ μ λΉ λ₯΄κ² μνν μ μλλ‘ λ‘κ·Έ ν μ΄λΈμ λ§μ§λ§μΌλ‘ μ λ°μ΄νΈλ λ μ½λμ κ°μ μ μ₯ν μ μμ
=> μΆμΆ μμ μ΄ μμνκ±°λ μλ£λ μκ°μ΄ μλλΌ λμ ν μ΄λΈμ MAX(LastUpdated) κ°μ λ°μ΄ν° μ¨μ΄νμ°μ€μ μ μ₯ν΄μΌ ν¨
μ¦λΆ μΆμΆμ΄ μ΅μ μ μ±λ₯μ μ΄μμ μ΄μ§λ§ μ΄λ€ ν μ΄λΈμ λν΄μλ κ°λ₯νμ§ μμ μ μλ λͺκ°μ§ λ¨μ μ΄ μμ
1. μμ λ νμ μΊ‘μ²λμ§ μμ
=> μλ³Έ MySQL ν μ΄λΈμμ νμ΄ μμ λλ©΄ μ μ μμΌλ©° ν΄λΉ λ μ½λλ λμ ν μ΄λΈμμλ μ무κ²λ λ³κ²½λμ§ μμ κ²μ²λΌ λ¨μμκ² λλ€
2. μλ³Έ ν μ΄λΈμλ λ§μ§λ§μΌλ‘ μ λ°μ΄νΈ λ μκ°μ λν μ λ’°ν μ μλ νμμ€ν¬νκ° μμ΄μΌ ν¨
=> μμ€ μμ€ν ν μ΄λΈμμ μ΄λ¬ν μ΄μ΄ λλ½λκ±°λ μμ μ μΌλ‘ μ λ°μ΄νΈλμ§ μλ κ²½μ°κ° νν¨
(κ°λ°μκ° μλ³Έ ν μ΄λΈμ λ μ½λλ₯Ό μ λ°μ΄νΈνκ³ LastUpdated νμμ€ν¬ν μ λ°μ΄νΈλ₯Ό μλ κ²μ λ§μ μ X)
κ·Έλ¬λ μ¦λΆ μΆμΆμ μ¬μ©νλ©΄ μ λ°μ΄νΈλ νμ λ μ½κ² μΊ‘μ²ν μ μλ€
λ‘λ λ¨κ³μμ μ 체 μΆμΆμ κ²½μ° μΌλ°μ μΌλ‘ λͺ©μ μ§μ μλ λμ ν μ΄λΈμ λ¨Όμ μμ (truncate)νκ³ μλ‘ μΆμΆλ λ°μ΄ν°λ₯Ό λμ λ°μ΄ν°μ λ‘λνλ€
=> μ΄ κ²½μ° λ°μ΄ν° μ¨μ΄νμ°μ€μ μ΅μ λ²μ μ νμ΄ λ¨μ
λ°μ΄ν° λ‘λ λ¨κ³μμ μ¦λΆ μΆμΆμ κ²½μ° κ²°κ³Ό λ°μ΄ν°κ° λͺ©μ μ§μ λμ ν μ΄λΈ λ°μ΄ν°μ μΆκ°λλ€
=> μ΄ κ²½μ° μλ³Έ λ°μ΄ν°λΏλ§ μλλΌ μ λ°μ΄νΈλ λ²μ μ λͺ¨λ κ°μ§κ² λ¨
(λ°μ΄ν°λ₯Ό λ³ννκ³ λΆμν λ λ κ°μ§ λ²μ μ λͺ¨λ κ°μ§κ³ μλ κ²μ΄ μ μ©ν μ μμ)
MySQL λ°μ΄ν°λ² μ΄μ€μμ μ 체 λ° μ¦λΆ μΆμΆμ λͺ¨λ λ°μ΄ν°λ² μ΄μ€μμ μ€νλμ§λ§ νμ΄μ¬ μ€ν¬λ¦½νΈμ μν΄ νΈλ¦¬κ±°λλ SQL 쿼리λ₯Ό μ¬μ©νμ¬ κ΅¬νν μλ μμ!
(env) pip install pymysql
PyMySQL λΌμ΄λΈλ¬λ¦¬λ₯Ό μ€μΉν΄μ£Όκ³
MySQL λ°μ΄ν°λ² μ΄μ€μ λν μ°κ²° μ 보λ₯Ό μ μ₯νκΈ° μν΄ pipeline.conf νμΌμ μ λ΄μ©μ μΆκ°ν΄μΌ νλ€
μ 체 μΆμΆ
μ΄μ extract_mysql_full.pyλΌλ μ νμ΄μ¬ μ€ν¬λ¦½νΈλ₯Ό μμ±ν΄μ
import pymysql
import csv
import boto3
import configparser
parser=configparser.ConfigParser()
parser.read("../pipeline.conf")
hostname = parser.get("mysql_config","hostname")
port = parser.get("mysql_config","port")
username = parser.get("mysql_config","username")
dbname = parser.get("mysql_config","database")
password = parser.get("mysql_config","password")
conn = pymysql.connect(host=hostname, user=username, passwd=password, db=dbname, port = int(port))
if conn is None :
print("Error connecting to the MySQL database")
else :
print("MySQL connection established!")
MySQL λ°μ΄ν°λ² μ΄μ€μ λν μ°κ²°μ μ΄κΈ°ννκ³
m_query = "SELECT * FROM Orders;"
local_filename = "order_extract.csv"
m_cursor = conn.cursor()
m_cursor.execute(m_query)
results = m_cursor.fetchall()
with open(local_filename, 'w') as fp :
csv_w = csv.writer(fp, delimiter='|')
csv_w.writerows(results)
fp.close()
m_cursor.close()
conn.close()
Orders ν μ΄λΈμ μ 체 μΆμΆμ μ€ννλ€
(μΆμΆμ μννκΈ° μν΄ pymysql λΌμ΄λΈλ¬λ¦¬μ cursor κ°μ²΄λ₯Ό μ¬μ©νμ¬ SELECT 쿼리λ₯Ό μ€ν)
=> νμ΄ν ('|') λ‘ κ΅¬λΆλ CSV νμΌμ μ
python extract_mysql_full.py
μ λͺ λ Ήμ΄λ‘ μ€νμ ν΄λ³΄λ©΄
CSV νμΌμ΄ λ‘μ»¬λ‘ μμ±λμμΌλ―λ‘ λμ€μ λ°μ΄ν° μ¨μ΄νμ°μ€λ λ€λ₯Έ λμμ λ‘λνλ €λ©΄ S3 λ²ν·μ μ λ‘λν΄μΌν¨
#aws_boto_credentials κ°μ λ‘λ
parser = configparser.ConfigParser()
parser.read("../pipeline.conf")
access_key = parser.get("aws_boto_credentials","access_key")
secret_key = parser.get("aws_boto_credentials","secret_key")
bucket_name = parser.get("aws_boto_credentials","bucket_name")
s3 = boto3.client('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key)
s3_file = local_filename
s3.upload_file(local_filename, bucket_name, s3_file)
μ΄λ κ² μ½λλ₯Ό μμ±νκ³ μ€νν΄λ³΄λ©΄
λ²ν·μ csv νμΌμ΄ μ±κ³΅μ μΌλ‘ μ λ‘λ λλ€!
μ¦λΆ μΆμΆ
π Redshiftμ κ΄ν μ€μ μ λ€μμ λμ¬ λ°μ΄ν° μ μ¬ λΆλΆμμ λ€λ£° μμ μ΄λΌ μ½λλ§ μ΄ν΄λ³΄μ!
λ³κ²½λ μ¬νλ§μ μ μ₯νλ―λ‘ Last Updatedλ‘ λΆν°μ λ³κ²½μ¬νμ ν¬μ°©νμ¬ λ°μ΄ν° μ¨μ΄νμ°μ€μ μ μ¬νλ€.
μ€ν¬λ¦½νΈμ μμμ μΌλ‘ extract_mysql_full.py νμΌμ 볡μ¬νμ¬ extract_mysql_incremental.py μ¬λ³Έμμ μμνλ©΄ μ’λ€
λ¨Όμ μλ³Έ Orders ν μ΄λΈμμ μΆμΆν λ§μ§λ§ λ μ½λμ νμμ€ν¬νλ₯Ό μ°Ύλλ€
=> μ΄λ κ² νλ €λ©΄ λ°μ΄ν° μ¨μ΄νμ°μ€μ Orders ν μ΄λΈμμ MAX(LastUpdated) κ°μ 쿼리νλ€
(env) pip install psycopg2
μ°μ Redshift ν΄λ¬μ€ν°μ μνΈμμ©νκΈ° μν΄ psycopg2 λΌμ΄λΈλ¬λ¦¬λ₯Ό μ€μΉν΄μ£Όκ³
Redshift ν΄λ¬μ€ν°μ μ°κ²°νκ³ μΏΌλ¦¬νμ¬ Orders ν μ΄λΈμμ MAX(LastUpdated) κ°μ κ°μ Έμ€λ μ½λλ₯Ό μμ±ν΄λ΄€λ€
# Redshift db connection μ 보λ₯Ό κ°μ Έμ΄
parser = configparser.ConfigParser()
parser.read("../pipeline.conf")
dbname = parser.get("aws_creds", "database")
user = parser.get("aws_creds", "username")
password = parser.get("aws_creds", "password")
host = parser.get("aws_creds", "host")
port = parser.get("aws_creds", "port")
# Redshift μ°κ²°
rs_conn = psycopg2.connect("dbname=" + dbname + " user=" + user + " password=" + password + " host=" + host + " port=" + port)
rs_sql = """SELECT COALESCE(MAX(LastUpdated), '1900-01-01') FROM Orders;"""
rs_cursor = rs_conn.cursor()
rs_cursor.execute(rs_sql)
result = rs_cursor.fetchone()
# μ€μ§ νλμ λ μ½λλ§ λ°νλ¨
last_updated_warehouse = result[0]
rs_cursor.close()
rs_conn.commit()
μμ rs_sqlμ 쿼리문μ λ°μ΄ν° μ¨μ΄νμ°μ€μ λ°μ΄ν°κ° λ§μ§λ§μΌλ‘ μ μ¬λ μμ μ κ°μ Έμ€κ³ κ·Έ μμ μ΄νλ‘μ λ°μ΄ν°λ€μ μλ³Έ λ°μ΄ν°λ² μ΄μ€(μ¬κΈ°μλ MySQL) μμ λΆλ¬μ λ³κ²½ μ¬νλ€μ΄ μλ€λ©΄ κ°μ Έμ¨λ€.
=> μ΄μ μ MySQLμ μ°κ²°νλ©° μμ±νλ μ½λμ κ±°μ λΉμ·νλ° μ€νν sql 쿼리λ₯Ό μ΄ν΄λ³΄λ©΄ LastUpdated μ MAX κ°μ SELECT νκ³ μκ³ λ§μ½ κ°μ΄ μμΌλ©΄ 1900-01-01 μ λ°νν΄μ€λ€!
μ΄ κ²½μ° μΏΌλ¦¬λ λ°μ΄ν°λ₯Ό λ³κ²½νμ§ μμΌλ―λ‘ μ»€λ°μ νμνμ§ μμ§λ§, μ°κ²°μ λ«μΌλ©΄μ νΈμΆνλ κ²μ΄ μΌλ°μ μ΄λΌ rs_conn.commit() λ μ¬μ©νλ€
last_updated_warehouseμ μ μ₯λ κ°μ μ¬μ©νμ¬ MySQL λ°μ΄ν°λ² μ΄μ€μμ μ€νλλ μΆμΆ 쿼리λ₯Ό μμ νκΈ° λλ¬Έμ μ΄μ μΆμΆ μμ μ€ν μ΄ν Orders ν μ΄λΈμμ μ λ°μ΄νΈλ λ μ½λλ§ κ°μ Έμ¬ μ μλ€!
MySQLμμμ μΆμΆ 쿼리λ λ€μκ³Ό κ°μ΄ μμ νλ€
m_query = """SELECT * FROM Orders WHERE LastUpdated > %s;"""
local_filename = "order_extract.csv"
m_cursor = conn.cursor()
m_cursor.execute(m_query, (last_updated_warehouse,))
μ 쿼리μλ last_update_warehouse κ°μ λν΄ %sλ‘ νμλλ μ리 νμμκ° ν¬ν¨λμ΄ μλλ° μ΄λ κ² νλ©΄ κ°μ΄ νν(λ°μ΄ν° μ§ν©μ μ μ₯νλ λ° μ¬μ©λλ λ°μ΄ν° μ ν)λ‘ cursorμ .execute() ν¨μμ μ λ¬λλ€!
=> μ΄λ SQL injection(μ£Όμ ) μ λ°©μ§νκΈ° μν΄ SQL 쿼리μ λ§€κ°λ³μλ₯Ό μΆκ°ν΄μ£Όλ μ μ νκ³ μμ ν λ°©λ²μ΄λ€.
PostgreSQL λ°μ΄ν°λ² μ΄μ€μμμ λ°μ΄ν° μΆμΆμ MySQLκ³Ό λ§€μ° μ μ¬ν΄μ μ€μ΅λ§ μ§ννκ³ λμ΄κ°μ΅λλ€!
MySQL λ°μ΄ν°μ μ΄μ§ λ‘κ·Έ 볡μ λ μ΄ν΄κ° μ μλΌμ μ±μ₯νκ³ λμμμ λ€μ λ€λ€λ³΄λλ‘ νκ² μ΅λλ€...
'π³ Data Engineering > Data Pipeline' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
λ°μ΄ν° μμ§ : λ°μ΄ν° λ‘λ (1) | 2024.07.03 |
---|---|
λ°μ΄ν° μμ§ : λ°μ΄ν° μΆμΆ (MongoDB, REST API, μΉ΄νμΉ΄ λ° Debezium) (1) | 2024.07.02 |
μΌλ°μ μΈ λ°μ΄ν° νμ΄νλΌμΈ ν¨ν΄ (1) | 2024.05.15 |
μ΅μ λ°μ΄ν° μΈνλΌ (0) | 2024.05.12 |
λ°μ΄ν° νμ΄νλΌμΈ μκ° (0) | 2024.05.06 |