EP09: Programming with Database
8: การเขียนโปรแกรมเชื่อมต่อฐานข้อมูล (Programming with Database)
ส่วนที่ 1: การบรรยาย
หัวข้อ: สถาปัตยกรรมระบบ IoT สำหรับ Smart Factory และบทนำสู่ Python
ภาพรวมสถาปัตยกรรม Smart Factory Data Pipeline
- ชั้นกายภาพ (Physical Layer): ESP32 + Sensor (เช่น เซ็นเซอร์อุณหภูมิ DHT22) ทำหน้าที่ “ตรวจจับ” ข้อมูลจากโลกจริง
- ชั้นสื่อสาร (Communication Layer): ข้อมูลถูกส่งผ่านเครือข่าย (เช่น Wi-Fi) โดยใช้โปรโตคอลสื่อสาร (เช่น HTTP, MQTT)
- ชั้นแอปพลิเคชัน (Application Layer): สคริปต์ Python ที่ทำงานบนคอมพิวเตอร์หรือเซิร์ฟเวอร์ ทำหน้าที่ “รับ” ข้อมูลจาก ESP32, “ประมวลผลเบื้องต้น”, และ “ส่งต่อ” ไปยังฐานข้อมูล
- ชั้นข้อมูล (Data Layer): ฐานข้อมูล (PostgreSQL/MySQL) ที่เราเรียนกันมา ทำหน้าที่ “จัดเก็บ” ข้อมูลอย่างมีโครงสร้าง
ทำไมต้องใช้ Python และ ESP32?
- Python:
- ภาษามนุษย์: ไวยากรณ์ (Syntax) อ่านง่าย เข้าใจง่าย เหมาะสำหรับผู้เริ่มต้น
- กาวชั้นดี (Glue Language): มี “คลังเครื่องมือ” หรือไลบรารี (Library) ขนาดใหญ่ที่ใช้เชื่อมต่อกับเทคโนโลยีอื่นๆ ได้อย่างง่ายดาย
- ไลบรารีสำคัญที่เราจะใช้:
psycopg2
(สำหรับ PostgreSQL) หรือ mysql-connector-python
(สำหรับ MySQL) -> ตัวแปลภาษาระหว่าง Python กับ SQL
pandas
-> สุดยอดเครื่องมือจัดการข้อมูล (จะใช้ในสัปดาห์ถัดๆ ไป)
- ESP32:
- คอมพิวเตอร์จิ๋วราคาถูก: เป็นไมโครคอนโทรลเลอร์ (Microcontroller) ที่มีประสิทธิภาพสูง
- ความสามารถครบครัน: มี Wi-Fi และ Bluetooth ในตัว เหมาะสำหรับงาน IoT
- บทบาทในโรงงาน: ใช้เป็นสมองกลของเซ็นเซอร์ต่างๆ เพื่ออ่านค่าและส่งข้อมูลเข้าระบบกลาง
หลักการทำงานของ Database Connector
- เปรียบเทียบ: Database Connector ก็เหมือน “ล่าม” หรือ “ทูต”
- โค้ด Python ของเราพูด “ภาษาไพธอน”
- ฐานข้อมูลของเราพูด “ภาษา SQL”
psycopg2
หรือ mysql-connector
ทำหน้าที่แปลคำสั่งจาก Python ให้เป็น SQL ที่ฐานข้อมูลเข้าใจ และแปลผลลัพธ์จาก SQL กลับมาเป็นข้อมูลที่ Python ใช้งานต่อได้
- ภาพรวมขั้นตอนการทำงานในโค้ด Python (The 4 Steps):
- Connect: สร้างการเชื่อมต่อ (ต้องระบุ ที่อยู่, ชื่อฐานข้อมูล, ผู้ใช้, รหัสผ่าน)
- Cursor: สร้าง “ตัวชี้” หรือ “รีโมต” สำหรับส่งคำสั่ง
- Execute: สั่งให้รีโมต “ทำงาน” โดยส่งคำสั่ง SQL เข้าไป
- Close: “ตัดการเชื่อมต่อ” เมื่อทำงานเสร็จ (สำคัญมาก!)
ส่วนที่ 2: การฝึกปฏิบัติ
หัวข้อ: Workshop: เขียนสคริปต์ Python แรกเพื่อคุยกับฐานข้อมูล
เครื่องมือ: คอมพิวเตอร์ที่มี Python, VS Code (หรือ Text Editor อื่นๆ), และเชื่อมต่อเครือข่ายกับ Database Server ได้
ขั้นตอนที่ 1: การติดตั้งและเตรียมสภาพแวดล้อม (Environment Setup)
- ติดตั้ง Python: (หากยังไม่มีในเครื่อง)
- แนะนำ
pip
(Package Installer for Python):
- เปิด Command Prompt หรือ Terminal
- สอนคำสั่ง
pip install <ชื่อไลบรารี>
- ติดตั้ง Database Connector:
- สำหรับ PostgreSQL:
pip install psycopg2-binary
- สำหรับ MySQL:
pip install mysql-connector-python
- แนะนำ VS Code: สอนการสร้างไฟล์ใหม่ (เช่น
connect_db.py
) และการเปิด Terminal ใน VS Code เพื่อรันสคริปต์
ขั้นตอนที่ 2: การเขียนสคริปต์เชื่อมต่อฐานข้อมูล (The Connection Script)
- ภารกิจ: ให้นักศึกษาเขียนโค้ดตาม และแก้ไขส่วนของ
conn_params
ให้เป็นข้อมูลของตัวเอง
Python# สำหรับ PostgreSQL
import psycopg2
# สำหรับ MySQL
# import mysql.connector
# 1. กำหนดข้อมูลสำหรับการเชื่อมต่อ
conn_params = {
"host": "127.0.0.1", # หรือ IP Address ของ Server
"database": "smart_factory_week4",
"user": "your_username",
"password": "your_password"
}
# 2. สร้างตัวแปรสำหรับเก็บการเชื่อมต่อ
conn = None
try:
# 3. พยายามเชื่อมต่อฐานข้อมูล
print("กำลังพยายามเชื่อมต่อฐานข้อมูล...")
# conn = psycopg2.connect(**conn_params) # สำหรับ PostgreSQL
# conn = mysql.connector.connect(**conn_params) # สำหรับ MySQL
print("เชื่อมต่อฐานข้อมูลสำเร็จ!")
except Exception as error:
# 4. หากเกิดข้อผิดพลาดในการเชื่อมต่อ
print(f"เกิดข้อผิดพลาดในการเชื่อมต่อ: {error}")
finally:
# 5. ตรวจสอบและปิดการเชื่อมต่อเสมอ ไม่ว่าจะสำเร็จหรือล้มเหลว
if conn is not None:
conn.close()
print("ตัดการเชื่อมต่อฐานข้อมูลแล้ว")
- ช่วงแก้ปัญหา (Troubleshooting): ปัญหา เช่น รหัสผ่านผิด, ติด Firewall, ชื่อฐานข้อมูลผิด, ลืมเปิด service ฐานข้อมูล
ขั้นตอนที่ 3: การดึงข้อมูลมาแสดงผล (Fetch & Display Data)
- ภารกิจ: ต่อยอดจากสคริปต์ที่เชื่อมต่อสำเร็จแล้ว ให้เพิ่มโค้ดส่วนของการดึงข้อมูลเข้ามา
Python# ... (โค้ดส่วนเชื่อมต่อเหมือนเดิม) ...
try:
print("กำลังพยายามเชื่อมต่อฐานข้อมูล...")
conn = psycopg2.connect(**conn_params)
print("เชื่อมต่อฐานข้อมูลสำเร็จ!")
# สร้าง Cursor object
cur = conn.cursor()
# ส่งคำสั่ง SQL เพื่อดึงข้อมูล
print("\n--- รายชื่อเครื่องจักรทั้งหมด ---")
cur.execute("SELECT machine_id, machine_name, location FROM machines;")
# ดึงผลลัพธ์ทั้งหมดมาเก็บไว้
all_machines = cur.fetchall()
# วนลูปเพื่อแสดงผลทีละแถว
for machine in all_machines:
print(f"ID: {machine[0]}, Name: {machine[1]}, Location: {machine[2]}")
# ปิด Cursor
cur.close()
except Exception as error:
print(f"เกิดข้อผิดพลาด: {error}")
finally:
if conn is not None:
conn.close()
print("\nตัดการเชื่อมต่อฐานข้อมูลแล้ว")
- มอบหมายงานย่อย: “ให้นักศึกษาแก้ไขโค้ดเพื่อดึงข้อมูลจากตาราง
employees
มาแสดงผลแทน”
เพิ่มตารางใหม่สำหรับ “Data Logs”
เพิ่มตารางใหม่ ขึ้นมาโดยเฉพาะเพื่อทำหน้าที่เป็น “สมุดบันทึกข้อมูลจากเซ็นเซอร์” (Sensor Data Logs) โดยตารางนี้จะเชื่อมโยงกลับไปยังตาราง machines
เดิม
การออกแบบตารางใหม่ชื่อว่า sensor_logs
ดังนี้ครับ
ตาราง: sensor_logs
ชื่อคอลัมน์ (Column Name) | ชนิดข้อมูล (Data Type) | คำอธิบาย (Description) |
log_id | BIGSERIAL (PostgreSQL) / BIGINT AUTO_INCREMENT (MySQL) | Primary Key รหัสของ Log แต่ละรายการ (ใช้ตัวเลขขนาดใหญ่เพราะข้อมูลจะเยอะมาก) |
timestamp_evt | TIMESTAMP WITH TIME ZONE | Timestamp สำคัญที่สุด! บอกว่าข้อมูลนี้เกิดขึ้นเมื่อไหร่ (เก็บ Timezone ด้วยเป็น Best Practice) |
machine_id_fk | INT | Foreign Key ชี้กลับไปยัง machine_id ในตาราง machines เพื่อให้รู้ว่าเป็นข้อมูลของเครื่องจักรใด |
metric_type | VARCHAR(50) | ชนิดของค่าที่วัดได้ เช่น ‘temperature’, ‘humidity’, ‘vibration’, ‘pressure’ |
metric_value | DECIMAL(10, 2) | ค่าที่วัดได้จากเซ็นเซอร์ (ใช้ DECIMAL เพื่อความแม่นยำ) |
ความสัมพันธ์ใหม่:
machines
1 เครื่อง จะมีความสัมพันธ์แบบ One-to-Many ไปยัง sensor_logs
- (เครื่องจักร 1 เครื่อง สามารถมี log data ได้เป็นล้านๆ records)
คำสั่ง SQL สำหรับสร้างตารางใหม่
SQLCREATE TABLE sensor_logs (
log_id BIGINT AUTO_INCREMENT PRIMARY KEY,
timestamp_evt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
machine_id_fk INT,
metric_type VARCHAR(50) NOT NULL,
metric_value DECIMAL(10, 2) NOT NULL,
FOREIGN KEY (machine_id_fk) REFERENCES machines(machine_id)
);