Thursday, June 26, 2025

การตั้งค่า SQL Instance เพื่อใช้งานกับ python + Flask

 การตั้งค่า SQL Instance เพื่อใช้งานกับ python + Flask

ขั้นตอนที่ 1: การตั้งค่า Cloud SQL Instance บน Google Cloud

  1. ไปที่ Cloud SQL: ใน Google Cloud Console, ไปที่ "SQL" ในเมนูด้านซ้าย
  2. สร้าง Instance: คลิก "Create Instance" แล้วเลือก Database Engine ที่คุณต้องการ (แนะนำ PostgreSQL หรือ MySQL เพราะใช้งานง่ายและมี Community ใหญ่)
  3. ตั้งชื่อ Instance: ตั้งชื่อ Instance ของคุณ (เช่น my-flask-app-db)
  4. กำหนดรหัสผ่าน Root: ตั้งรหัสผ่านสำหรับ user root (หรือ postgres สำหรับ PostgreSQL) และเก็บไว้ให้ปลอดภัย
  5. เลือก Region: เลือก Region ที่ใกล้เคียงกับ App Engine ของคุณเพื่อลด Latency
  6. ตั้งค่าเวอร์ชันและ Spec: เลือกเวอร์ชันของ Database (เช่น PostgreSQL 14 หรือ MySQL 8) และขนาดของ Instance (Machine Type) ตามความต้องการของแอปพลิเคชันของคุณ
  7. ตั้งค่า Connection: สำคัญมาก! ในส่วนของ "Connections" ให้ตรวจสอบว่า "Public IP" ถูกปิดอยู่ และเลือก "Private IP" เพื่อให้ App Engine เชื่อมต่อผ่าน Private Network ที่มีความปลอดภัยและรวดเร็วกว่า
  8. กำหนด Access: ในส่วนของ "Connections" -> "Authorized networks" คุณสามารถเพิ่ม IP Address ของคุณเองเพื่อเข้าถึง Instance จากเครื่อง Local สำหรับการพัฒนาและทดสอบได้
  9. สร้าง Database: หลังจากสร้าง Instance เสร็จแล้ว ให้สร้าง Database ขึ้นมา 1 ตัวสำหรับแอปพลิเคชันของคุณ (เช่น myapp_db)

ขั้นตอนที่ 2: การเตรียมโค้ด Flask สำหรับ Cloud SQL

ในโค้ด Flask ของคุณ จะต้องมีการเชื่อมต่อกับ Cloud SQL ที่แตกต่างจากการเชื่อมต่อกับ Local Database เล็กน้อยครับ เราจะใช้ Unix socket สำหรับการเชื่อมต่อที่ปลอดภัยและมีประสิทธิภาพบน App Engine

สิ่งที่ต้องใช้:

  1. Flask-SQLAlchemy (ORM สำหรับ Flask)
  2. Driver สำหรับ Database (เช่น PyMySQL สำหรับ MySQL หรือ psycopg2 สำหรับ PostgreSQL)
  3. google-cloud-sql-connector (สำหรับเชื่อมต่อกับ Cloud SQL อย่างปลอดภัย)

ตัวอย่างโค้ด (สำหรับ PostgreSQL):

ติดตั้ง Library ที่จำเป็น:

Bash
pip install Flask Flask-SQLAlchemy PyMySQL

สำหรับ PostgreSQL ให้ใช้ psycopg2-binary แทน PyMySQL

Bash
pip install Flask Flask-SQLAlchemy psycopg2-binary

app.py (ไฟล์หลักของ Flask app)

Python
import os
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# --- Cloud SQL configuration ---
# Retrieve connection details from environment variables set in app.yaml
# These variables are securely managed by App Engine.
DB_USER = os.environ.get('CLOUD_SQL_USERNAME')
DB_PASS = os.environ.get('CLOUD_SQL_PASSWORD')
DB_NAME = os.environ.get('CLOUD_SQL_DATABASE_NAME')
CONNECTION_NAME = os.environ.get('CLOUD_SQL_CONNECTION_NAME') # This is the unique name of your Cloud SQL instance

# Build the connection string
# We use Unix socket for connection on App Engine, which is secure and fast.
# For local testing, you might need a different connection string.
# The format depends on the database engine.
# For PostgreSQL:
app.config['SQLALCHEMY_DATABASE_URI'] = (
    f"postgresql+psycopg2://{DB_USER}:{DB_PASS}@/{DB_NAME}?host=/cloudsql/{CONNECTION_NAME}"
)
# For MySQL:
# app.config['SQLALCHEMY_DATABASE_URI'] = (
#    f"mysql+pymysql://{DB_USER}:{DB_PASS}@/{DB_NAME}?unix_socket=/cloudsql/{CONNECTION_NAME}"
# )

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

# Define your SQLAlchemy models here
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

    def __repr__(self):
        return f'<User {self.username}>'

@app.route('/')
def index():
    return "Flask App is running!"

@app.route('/users')
def get_users():
    users = db.session.execute(db.select(User)).scalars().all()
    user_list = [{'id': user.id, 'username': user.username, 'email': user.email} for user in users]
    return jsonify(user_list)

@app.route('/create_user/<username>/<email>')
def create_user(username, email):
    new_user = User(username=username, email=email)
    db.session.add(new_user)
    db.session.commit()
    return f'User {username} created successfully!'

if __name__ == '__main__':
    # In a local environment, you can run this to create tables
    # Before running, make sure your local connection string is set up or you're connected to the DB.
    # For GAE, this part is not needed as you should run migrations separately.
    # with app.app_context():
    #    db.create_all()
    
    # Use environment variable for port on App Engine
    app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 8080)), debug=True)

ขั้นตอนที่ 3: การตั้งค่า app.yaml สำหรับ App Engine

ไฟล์ app.yaml เป็นไฟล์สำคัญในการกำหนดค่า Environment ของ App Engine เพื่อให้สามารถเชื่อมต่อกับ Cloud SQL ได้อย่างถูกต้อง

app.yaml

YAML
runtime: python39  # Or python310, python311, etc.
entrypoint: gunicorn -w 4 -k gevent -b :$PORT app:app

env_variables:
  # These variables will be available in your Flask application code
  CLOUD_SQL_USERNAME: 'your_db_user' # e.g., 'postgres' or 'root'
  CLOUD_SQL_PASSWORD: 'your_db_password'
  CLOUD_SQL_DATABASE_NAME: 'your_database_name' # e.g., 'myapp_db'
  CLOUD_SQL_CONNECTION_NAME: 'your-project-id:your-region:your-instance-name' # e.g., 'my-project:asia-southeast1:my-flask-app-db'

beta_settings:
  # This setting connects your App Engine service to your Cloud SQL instance
  cloud_sql_instances: 'your-project-id:your-region:your-instance-name'

หมายเหตุ:

  • CLOUD_SQL_CONNECTION_NAME สามารถหาได้จากหน้า Overview ของ Cloud SQL Instance ของคุณใน GCP Console (จะเป็นรูปแบบ project-id:region:instance-name)
  • entrypoint: แนะนำให้ใช้ Gunicorn เพื่อทำ Production Server ที่มีประสิทธิภาพสูง
  • beta_settings: ส่วนนี้สำคัญมากสำหรับเชื่อมต่อกับ Cloud SQL

ขั้นตอนที่ 4: การ Deploy แอปพลิเคชัน

  1. สร้าง requirements.txt:

    Bash
    pip freeze > requirements.txt
    

    (ตรวจสอบให้แน่ใจว่ามี Flask, Flask-SQLAlchemy, PyMySQL หรือ psycopg2-binary, และ gunicorn อยู่ในไฟล์)

  2. ตั้งค่า gcloud:

    Bash
    gcloud init
    gcloud auth application-default login # This is important for local testing and authentication
    
  3. Deploy:

    Bash
    gcloud app deploy
    

    คำสั่งนี้จะทำการ Deploy โค้ดของคุณไปยัง App Engine และสร้าง Environment ตามที่กำหนดไว้ใน app.yaml

ข้อควรระวังและ Best Practices

  • Database Schema Migration: การใช้ db.create_all() เหมาะสำหรับการพัฒนาและทดสอบเท่านั้น ใน Production ควรใช้เครื่องมือทำ Database Migration เช่น Alembic เพื่อจัดการการเปลี่ยนแปลง Schema ของ Database อย่างเป็นระบบ
  • Secret Management: ไม่ควร hardcode รหัสผ่านในโค้ดหรือ app.yaml ควรใช้ Environment Variables หรือ Secret Manager เพื่อความปลอดภัยสูงสุด
  • Connection Pool: SQLAlchemy จัดการ Connection Pool ให้คุณโดยอัตโนมัติ ทำให้การเชื่อมต่อมีประสิทธิภาพมากขึ้น
  • Security: ตรวจสอบให้แน่ใจว่า Cloud SQL Instance ของคุณถูกตั้งค่าให้เข้าถึงได้เฉพาะจาก App Engine (ผ่าน Private IP) และจำกัดสิทธิ์ของ user ใน Database ให้เหมาะสม

หากคุณทำตามขั้นตอนเหล่านี้ คุณจะสามารถ Deploy Flask Web Application ที่เชื่อมต่อกับ Cloud SQL บน Google App Engine ได้อย่างราบรื่นและมีประสิทธิภาพในระดับ Production ครับ!


No comments: