Python + MySQL холбох
Python-оос MySQL өгөгдлийн сантай харилцахын тулд mysql-connector-python package ашиглана. Энэ хичээлд холболт үүсгэх, cursor ашиглах, parameterized query бичих, context manager ашиглах аргыг сурна.
mysql-connector-python суулгах
pip install mysql-connector-python
Энгийн холболт
import mysql.connector
conn = mysql.connector.connect(
host='localhost',
user='root',
password='нууц_үг',
database='myshop'
)
cursor = conn.cursor()
cursor.execute('SELECT * FROM users')
rows = cursor.fetchall()
for row in rows:
print(row)
cursor.close()
conn.close()
Cursor бол SQL командыг гүйцэтгэж, үр дүнг авах объект юм. Нэг холболт дээр олон cursor үүсгэж болно.
Context Manager — зөв арга
with блок ашиглахад холболт автоматаар хаагдана — close() мартах аюулгүй:
import mysql.connector
config = {
'host': 'localhost',
'user': 'root',
'password': 'нууц_үг',
'database': 'myshop'
}
with mysql.connector.connect(**config) as conn:
with conn.cursor() as cursor:
cursor.execute('SELECT * FROM users')
rows = cursor.fetchall()
for row in rows:
print(row)
-- Энд гарахад conn, cursor автоматаар хаагдана
Cursor-ийн төрлүүд
Үндсэн cursor — tuple буцаана
cursor = conn.cursor()
cursor.execute('SELECT id, name, email FROM users')
row = cursor.fetchone() -- нэг мөр
print(row) -- (1, 'Болд', 'bold@example.com')
rows = cursor.fetchall() -- бүх мөр
Dictionary cursor — dict буцаана
cursor = conn.cursor(dictionary=True)
cursor.execute('SELECT id, name, email FROM users')
row = cursor.fetchone()
print(row['name']) -- 'Болд'
print(row['email']) -- 'bold@example.com'
Dictionary cursor ашиглах нь баганыг индексээр биш нэрээр нэвтрэх боломж олгодог тул унших хялбар.
Parameterized Query — SQL Injection-оос хамгаалах
Хэрэглэгчийн оролтыг шууд query-д залгах нь аюултай:
-- БУРУУ — SQL Injection-д өртөмтгий!
name = input('Нэр оруул: ')
cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")
Зөв арга — %s placeholder ашиглах:
-- ЗӨВ — parameterized query
def find_user_by_name(cursor, name):
query = 'SELECT * FROM users WHERE name = %s'
cursor.execute(query, (name,)) -- tuple байх шаардлагатай
return cursor.fetchall()
-- Ашиглах
with mysql.connector.connect(**config) as conn:
with conn.cursor(dictionary=True) as cursor:
users = find_user_by_name(cursor, 'Болд')
print(users)
Утга нэг байсан ч (name,) гэж tuple хэлбэрт өгнө.
Олон утга:
def find_products_in_range(cursor, min_price, max_price):
query = 'SELECT * FROM products WHERE price BETWEEN %s AND %s'
cursor.execute(query, (min_price, max_price))
return cursor.fetchall()
CRUD үйлдлүүд
Мэдээлэл нэмэх — INSERT
def create_user(conn, name, email, password_hash):
with conn.cursor() as cursor:
query = '''
INSERT INTO users (name, email, password)
VALUES (%s, %s, %s)
'''
cursor.execute(query, (name, email, password_hash))
conn.commit()
return cursor.lastrowid -- шинэ мөрийн ID
conn.commit() дуудахгүй бол өөрчлөлт хадгалагдахгүй.
Олон мөр нэг дор нэмэх — executemany
def insert_products(conn, products):
with conn.cursor() as cursor:
query = 'INSERT INTO products (name, price, stock) VALUES (%s, %s, %s)'
cursor.executemany(query, products)
conn.commit()
print(f'{cursor.rowcount} бараа нэмэгдлээ')
-- Ашиглах
products = [
('Гар утас', 1_200_000, 50),
('Чихэвч', 150_000, 200),
('Цэнэгч', 45_000, 500),
]
with mysql.connector.connect(**config) as conn:
insert_products(conn, products)
Мэдээлэл хайх — SELECT
def get_all_products(conn):
with conn.cursor(dictionary=True) as cursor:
cursor.execute('SELECT * FROM products ORDER BY price DESC')
return cursor.fetchall()
def get_product_by_id(conn, product_id):
with conn.cursor(dictionary=True) as cursor:
cursor.execute(
'SELECT * FROM products WHERE id = %s',
(product_id,)
)
return cursor.fetchone() -- None буцаах боломжтой
Мэдээлэл өөрчлөх — UPDATE
def update_stock(conn, product_id, new_stock):
with conn.cursor() as cursor:
cursor.execute(
'UPDATE products SET stock = %s WHERE id = %s',
(new_stock, product_id)
)
conn.commit()
if cursor.rowcount == 0:
raise ValueError(f'ID={product_id} бараа олдсонгүй')
return cursor.rowcount
Мэдээлэл устгах — DELETE
def delete_product(conn, product_id):
with conn.cursor() as cursor:
cursor.execute(
'DELETE FROM products WHERE id = %s',
(product_id,)
)
conn.commit()
return cursor.rowcount > 0
Transaction
def place_order(conn, user_id, items):
try:
conn.start_transaction()
with conn.cursor() as cursor:
-- Захиалга үүсгэх
cursor.execute(
'INSERT INTO orders (user_id, total) VALUES (%s, 0)',
(user_id,)
)
order_id = cursor.lastrowid
total = 0
-- Мөрүүд нэмэх
for item in items:
cursor.execute(
'''INSERT INTO order_items
(order_id, product_id, quantity, price)
VALUES (%s, %s, %s, %s)''',
(order_id, item['product_id'], item['quantity'], item['price'])
)
total += item['quantity'] * item['price']
-- Нийт дүн шинэчлэх
cursor.execute(
'UPDATE orders SET total = %s WHERE id = %s',
(total, order_id)
)
conn.commit()
print(f'Захиалга #{order_id} амжилттай')
return order_id
except mysql.connector.Error as err:
conn.rollback()
print(f'Алдаа: {err}')
raise
Алдаа зохицуулах
import mysql.connector
from mysql.connector import errorcode
try:
conn = mysql.connector.connect(**config)
except mysql.connector.Error as err:
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
print('Хэрэглэгчийн нэр эсвэл нууц үг буруу')
elif err.errno == errorcode.ER_BAD_DB_ERROR:
print('Өгөгдлийн сан олдсонгүй')
else:
print(f'Холболтын алдаа: {err}')
raise
Бүтэн жишээ: Бараа удирдах
import mysql.connector
config = {
'host': 'localhost',
'user': 'root',
'password': 'нууц_үг',
'database': 'myshop'
}
def get_products(min_price=None):
with mysql.connector.connect(**config) as conn:
with conn.cursor(dictionary=True) as cursor:
if min_price is not None:
cursor.execute(
'SELECT * FROM products WHERE price >= %s ORDER BY price',
(min_price,)
)
else:
cursor.execute('SELECT * FROM products ORDER BY price')
return cursor.fetchall()
def add_product(name, price, stock):
with mysql.connector.connect(**config) as conn:
with conn.cursor() as cursor:
cursor.execute(
'INSERT INTO products (name, price, stock) VALUES (%s, %s, %s)',
(name, price, stock)
)
conn.commit()
return cursor.lastrowid
-- Ажиллуулах
products = get_products(min_price=100_000)
for p in products:
print(f"{p['name']}: {p['price']:,}₮ — {p['stock']} ширхэг")
new_id = add_product('Таблет', 800_000, 30)
print(f'Шинэ бараа нэмэгдлээ, ID: {new_id}')
Дараагийн хичээлд:
MySQL шилдэг туршлага — нэрлэлтийн дүрэм, index стратеги, аюулгүй байдал, backup-ийн зөв хандлагыг үзнэ.