Pandas (P2): Phân tích dữ liệu từ Database

08 tháng 02, 2025 - 112 lượt xem

1. Cài đặt thư viện cần thiết

Trước tiên, chúng ta cần cài đặt pandas và nắm được cơ bản về Pandas
Link tham khảo: https://techmaster.vn/posts/38296/gioi-thieu-ve-pandas-trong-python-cong-cu-manh-me-cho-xu-ly-du-lieu

Cài đặt một số thư viện cần thiết:

pip install pandas pymysql

pandas: Để xử lý dữ liệu.
pymysql: Để kết nối với MySQL.

2. Kết nối với MySQL và đọc dữ liệu

Dưới đây là code chi tiết để kết nối với MySQL và đọc dữ liệu từ bảng

import pymysql

# Thông tin kết nối MySQL
host = 'ip server'
port = 3306
database = 'DB_name'
username = 'username'
password = 'password'

# Kết nối với MySQL
try:
    connection = pymysql.connect(
        host=host,
        port=port,
        user=username,
        password=password,
        database=database
    )
    print("Kết nối MySQL thành công!")

    # Truy vấn dữ liệu từ bảng file_upload
    query = "SELECT column1, column2 FROM table_name"
    df = pd.read_sql_query(query, connection)

    # Hiển thị dữ liệu
    print("Dữ liệu từ bảng:")
    print(df)

except pymysql.Error as e:
    print(f"Lỗi kết nối MySQL: {e}")

finally:
    # Đóng kết nối
    if connection:
        connection.close()
        print("Đã đóng kết nối MySQL.")

3. Giải thích code

a. Thông tin kết nối
host: Địa chỉ IP của máy chủ MySQL .

port: Cổng kết nối MySQL (mặc định là 3306).

database: Tên cơ sở dữ liệu.

username: Tên người dùng.

password: Mật khẩu.

b. Kết nối với MySQL
Sử dụng pymysql.connect() để tạo kết nối đến MySQL.

Nếu kết nối thành công, thông báo “Kết nối MySQL thành công!” sẽ được in ra.

c. Truy vấn dữ liệu
Sử dụng pd.read_sql_query() để thực hiện truy vấn SQL và đọc dữ liệu vào DataFrame.

Câu lệnh SQL: column1, column2,… FROM table_name để lấy dữ liệu từ bảng table_name.

d. Hiển thị dữ liệu
Dữ liệu được lưu vào DataFrame df và in ra màn hình.

e. Xử lý lỗi và đóng kết nối
Nếu có lỗi xảy ra, thông báo lỗi sẽ được in ra.

Lưu ý: Luôn đóng kết nối MySQL sau khi hoàn thành công việc bằng connection.close() và nên lưu thông tin kết nối ở một nơi khác để bảo mật.

4. Ví dụ

Giả sửa tôi muốn truy vấn lấy thông tin danh sách file của tôi từ bảng file_upload

import pymysql

# Thông tin kết nối MySQL
host = 'localhost'
port = 3306
database = 'techmaster_db'
username = 'techmaster'
password = 'hoclacoviec'

# Kết nối với MySQL
try:
    connection = pymysql.connect(
        host=host,
        port=port,
        user=username,
        password=password,
        database=database
    )
    print("Kết nối MySQL thành công!")

    # Truy vấn dữ liệu từ bảng file_upload
    query = "SELECT ID, file_path FROM file_upload"
    df = pd.read_sql_query(query, connection)

    # Hiển thị dữ liệu
    print("Dữ liệu từ bảng file_upload:")
    print(df)

except pymysql.Error as e:
    print(f"Lỗi kết nối MySQL: {e}")

finally:
    # Đóng kết nối
    if connection:
        connection.close()
        print("Đã đóng kết nối MySQL.")

Kết quả khi chạy code sẽ là:

Dữ liệu từ bảng file_upload:
   ID          file_path
0   1  /uploads/file1.txt
1   2  /uploads/file2.jpg
2   3  /uploads/file3.pdf
Đã đóng kết nối MySQL.

Bạn cũng có thể thực hiện phân trang dữ liệu:

import pymysql
import math

# Thông tin kết nối MySQL
host = 'localhost'
port = 3306
database = 'techmaster_db'
username = 'techmasterat'
password = 'hoclacoviec'

def query_with_pagination(connection, page_number, page_size):
    """
    Truy vấn dữ liệu từ bảng file_upload với phân trang và tính toán tổng số trang trong một truy vấn.

    :param connection: Kết nối MySQL
    :param page_number: Số trang (bắt đầu từ 1)
    :param page_size: Số lượng bản ghi trên mỗi trang
    :return: DataFrame chứa dữ liệu và thông tin về tổng số trang
    """
    # Tính offset cho phân trang
    offset = (page_number - 1) * page_size

    # Truy vấn kết hợp lấy dữ liệu và tổng số bản ghi
    query = f"""
        SELECT SQL_CALC_FOUND_ROWS ID, file_path 
        FROM file_upload 
        LIMIT {page_size} OFFSET {offset}
    """
    df = pd.read_sql_query(query, connection)

    # Truy vấn tổng số bản ghi từ câu lệnh SQL_CALC_FOUND_ROWS
    total_query = "SELECT FOUND_ROWS()"
    total_records = pd.read_sql_query(total_query, connection).iloc[0, 0]

    # Tính toán tổng số trang
    total_pages = math.ceil(total_records / page_size)

    return df, page_number, total_pages

# Ví dụ sử dụng
page_number = 1  # Trang 1
page_size = 5    # 5 bản ghi mỗi trang

# Kết nối với MySQL
try:
    connection = pymysql.connect(
        host=host,
        port=port,
        user=username,
        password=password,
        database=database
    )
    print("Kết nối MySQL thành công!")

    # Lấy dữ liệu và thông tin trang
    df, page_number, total_pages = query_with_pagination(connection, page_number, page_size)

    # Hiển thị dữ liệu và thông tin trang
    print(f"Dữ liệu từ trang {page_number} (tổng số trang: {total_pages}):")
    print(df)

except pymysql.Error as e:
    print(f"Lỗi kết nối MySQL: {e}")

finally:
    # Đóng kết nối
    if connection:
        connection.close()
        print("Đã đóng kết nối MySQL.")

Giải thích:

  • SQL_CALC_FOUND_ROWS: Trong câu truy vấn chính, chúng ta sử dụng SQL_CALC_FOUND_ROWS để yêu cầu MySQL tính tổng số bản ghi mà không cần phải làm một truy vấn riêng biệt. Điều này giúp giảm số lần truy vấn cần thực hiện.
  • FOUND_ROWS(): Sau khi thực hiện truy vấn chính, chúng ta thực hiện một truy vấn bổ sung rất nhẹ để lấy tổng số bản ghi (SELECT FOUND_ROWS()), giúp chúng ta tính toán tổng số trang mà không cần phải quét lại toàn bộ bảng.
  • Hiệu suất: Việc tính toán tổng số bản ghi và phân trang trong một lần truy vấn sẽ giúp cải thiện hiệu suất và giảm tải cho cơ sở dữ liệu, đặc biệt khi dữ liệu lớn.
pandas
pandas

Bình luận

avatar
Trịnh Minh Cường 2025-02-09 05:15:40.487874 +0000 UTC

Tuyệt vời Kungfu Techmaster !

Avatar
* Vui lòng trước khi bình luận.
Ảnh đại diện
  0 Thích
0