Thursday, November 21, 2024

[REST API] – FLASK PYTHON #4: Viết API thêm dữ liệu vào Database

-

1. Tổng quan.

Viết chương trình để thêm dữ liệu vào cơ sở dữ liệu MySQL là một phần quan trọng của phát triển ứng dụng web và các hệ thống dựa trên cơ sở dữ liệu. Quá trình này thường được thực hiện để lưu trữ thông tin người dùng, dữ liệu ứng dụng, hoặc bất kỳ loại dữ liệu nào có thể cần được theo dõi và truy vấn sau này.

Dưới đây là một số kiến thức quan trọng liên quan đến việc thêm dữ liệu vào cơ sở dữ liệu MySQL:

  • Kiến thức về MySQL: Để thêm dữ liệu vào cơ sở dữ liệu MySQL, bạn cần hiểu về cách MySQL hoạt động, cú pháp SQL (Structured Query Language) để thực hiện các thao tác như INSERT, và cách thiết lập cơ sở dữ liệu MySQL trên máy chủ.
  • Kết nối đến Cơ sở dữ liệu: Bạn cần biết cách thiết lập kết nối đến cơ sở dữ liệu MySQL từ ứng dụng của mình. Điều này bao gồm việc xác định máy chủ cơ sở dữ liệu, tên người dùng và mật khẩu để truy cập cơ sở dữ liệu.
  • Sử dụng Thư viện hoặc ORM (Object-Relational Mapping): Bạn có thể viết mã SQL trực tiếp hoặc sử dụng thư viện hoặc ORM để tạo và thực hiện các truy vấn SQL. Sử dụng ORM giúp quản lý cơ sở dữ liệu dễ dàng hơn và giảm nguy cơ lỗi.
  • Kiến thức về Ngôn ngữ lập trình: Bạn cần biết ngôn ngữ lập trình mà bạn đang sử dụng để viết chương trình. Thêm dữ liệu vào cơ sở dữ liệu thường liên quan đến việc tạo và quản lý đối tượng dữ liệu, sau đó thực hiện thao tác INSERT để lưu trữ chúng.
  • Kiến thức về Bảo mật: Bảo mật là một phần quan trọng khi thêm dữ liệu vào cơ sở dữ liệu. Bạn cần biết cách bảo vệ dữ liệu khỏi các cuộc tấn công SQL Injection bằng cách sử dụng câu lệnh tham số hóa hoặc các biện pháp bảo mật khác.
  • Kiến thức về Xử lý Ngoại lệ (Exception Handling): Cần biết cách xử lý các trường hợp ngoại lệ khi gặp lỗi trong quá trình thêm dữ liệu, chẳng hạn như mất kết nối đến cơ sở dữ liệu hoặc lỗi cú pháp SQL.
  • Kiến thức về Giao dịch (Transactions): Nếu bạn cần thực hiện nhiều truy vấn và đảm bảo tính nhất quán của dữ liệu, bạn cần biết cách sử dụng giao dịch để thực hiện các truy vấn theo cách an toàn.
  • Kiến thức về Cơ sở dữ liệu Tương tác: Nắm vững cách tương tác với cơ sở dữ liệu bao gồm INSERT (thêm dữ liệu mới), SELECT (truy vấn dữ liệu), UPDATE (cập nhật dữ liệu), DELETE (xoá dữ liệu), và các tác vụ liên quan khác.
  • Kiến thức về Các Kiểu Dữ Liệu trong Cơ sở dữ liệu: Biết cách ánh xạ dữ liệu từ đối tượng trong ngôn ngữ lập trình của bạn sang kiểu dữ liệu phù hợp trong cơ sở dữ liệu MySQL, chẳng hạn như chuỗi, số, ngày tháng, và nhiều loại khác.
  • Kiến thức về Quyền Truy cập và Phân quyền: Hiểu về cách quản lý quyền truy cập đến cơ sở dữ liệu, chẳng hạn như quyền SELECT, INSERT, UPDATE và DELETE.

Khi bạn có kiến thức về các khía cạnh này và đã xây dựng một ứng dụng có kết nối cơ sở dữ liệu MySQL, bạn có thể viết mã để thêm dữ liệu vào cơ sở dữ liệu một cách an toàn và hiệu quả.

2. Thực hành.

Ở phần này chúng ta chỉ làm các file theo cây thư mục này nhé.

devnet
├── cisco_os
│   ├── __init__.py
│   ├── backend
│   │   └── arp
│   │       ├── controller.py
│   │       ├── getdata.py
│   │       └── services.py
│   ├── config.py
│   ├── extension.py
│   └── model.py
├── network.py
└── venv
    ├── db_install.sh
    └── requirements.txt
  • config.py
import os
from dotenv import load_dotenv

load_dotenv()
SECRET_KEY = os.environ.get("KEY")
SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URL")
SQLALCHEMY_TRACK_MODIFICATIONS = False
  • .env
KEY = "hoanghd-secret-key"
DATABASE_URL = 'mysql://hoanghd:Hoanghd164@192.168.13.200/cisco_info'
  • __init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from .backend.arp.controller import get_arp_bl
from .model import db

def create_db(app):
    with app.app_context():
        db.create_all()
        print("Created DB!")

def create_cisco_os_app(config_file="config.py"):
    cisco_os = Flask(__name__)
    cisco_os.config.from_pyfile(config_file)
    db.init_app(cisco_os)
    create_db(cisco_os)
    cisco_os.register_blueprint(get_arp_bl)

    return cisco_os
  • controller.py
from flask import Blueprint, request
import json
from .services import (update_or_insert_arp_service, get_all_arp_from_device_service, get_all_arp_from_db_service, get_arp_by_id_from_db_service, add_arp_service)

get_arp_bl = Blueprint("get_arp_bl", __name__)

@get_arp_bl.route("/import_all_arp", methods=['GET'])
def import_all_arp():
    return update_or_insert_arp_service()

@get_arp_bl.route("/get_all_arp_from_device", methods=['GET'])
def get_all_arp_from_device():
    return get_all_arp_from_device_service()

@get_arp_bl.route("/get_all_arp_from_db", methods=['GET'])
def get_all_arp_from_db():
    return get_all_arp_from_db_service()

@get_arp_bl.route('/get_arp/<int:entry_id>', methods=["GET"])
def route_get_arp_by_id(entry_id):
    arp_data = get_arp_by_id_from_db_service(entry_id)
    if arp_data:
        return json.dumps(arp_data), 200, {'Content-Type': 'application/json'}
    else:
        return "Không tìm thấy dữ liệu ARP với ID đã chỉ định", 404
    
@get_arp_bl.route("/add_arp", methods=['POST'])
def add_arp():
    return add_arp_service()
  • services.py
from flask import request
from .getdata import merged_arp_data
from ...model import db, cisco_arp

def get_all_arp_from_device_service():
    arp_data = merged_arp_data()
    return arp_data

def get_all_arp_from_db_service():
    all_arp_entries = cisco_arp.query.all()
    arp_data = []
    for entry in all_arp_entries:
        arp_data.append({
            "id": entry.id,
            "address": entry.address,
            "device": entry.device,
            "interface": entry.interface,
            "mac_address": entry.mac_address,
            "ports": entry.ports
        })
    return arp_data

def get_arp_by_id_from_db_service(entry_id):
    arp_entry = cisco_arp.query.filter_by(id=entry_id).first()
    if arp_entry:
        arp_data = {
            "id": arp_entry.id,
            "address": arp_entry.address,
            "device": arp_entry.device,
            "interface": arp_entry.interface,
            "mac_address": arp_entry.mac_address,
            "ports": arp_entry.ports
        }
        return arp_data
    else:
        return None

def update_or_insert_arp_service():
    arp_data = merged_arp_data()
    for item in arp_data:
        address = item['address']
        device = item['device']
        interface = item['interface']
        mac_address = item['mac_address']
        ports = item['ports']
        existing_entry = cisco_arp.query.filter_by(address=address).first()

        if existing_entry:
            existing_entry.device = device
            existing_entry.interface = interface
            existing_entry.mac_address = mac_address
            existing_entry.ports = ports
            print("Update %s into database sussess!!!" %(address))
        else:
            new_entry = cisco_arp(address=address, device=device, interface=interface, mac_address=mac_address, ports=ports)
            db.session.add(new_entry)
            print("Add %s into database sussess!!!" %(address))
        db.session.commit()
        
    return "Add all arp into database sussess!!!"

def add_arp_service():
    try:
        address = request.json['address']
        device = request.json['device']
        interface = request.json['interface']
        mac_address = request.json['mac_address']
        ports = request.json['ports']

        existing_arp = cisco_arp.query.filter_by(address=address).first()

        if existing_arp:
            return "ARP address already exists in the database."
        else:
            new_arp = cisco_arp(address=address, device=device, interface=interface, mac_address=mac_address, ports=ports)
            db.session.add(new_arp)
            db.session.commit()

            print("Successfully added %s to the database!!!" % (address))
            return "Added successfully!!!"
    except Exception as e:
        print("Error when adding ARP:", str(e))
        return "Error when adding ARP:", str(e)
  • model.py
from .extension import db

class cisco_arp(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    address = db.Column(db.String(255))
    device = db.Column(db.String(255))
    interface = db.Column(db.String(255))
    mac_address = db.Column(db.String(255))
    ports = db.Column(db.String(255))

    def __init__(self, address, device, interface, mac_address, ports):
        self.address = address
        self.device = device
        self.interface = interface
        self.mac_address = mac_address
        self.ports = ports
  • extension.py
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
  • network.py
from cisco_os import create_cisco_os_app

if __name__ == "__main__":
    cisco_network = create_cisco_os_app()
    cisco_network.run(debug=True, host='0.0.0.0', port=5000)
  • getdata.py
def merged_arp_data():
    arp_data = [
        {
            "address": "103.110.128.4",
            "device": "42.96.37.41",
            "interface": "Vlan76",
            "mac_address": "7cc2.5527.a594",
            "ports": "Po4"
        },
        {
            "address": "103.110.128.3",
            "device": "42.96.37.41",
            "interface": "Vlan76",
            "mac_address": "7cc2.5527.a8b0",
            "ports": "Po3"
        },
        {
            "address": "103.110.128.6",
            "device": "42.96.37.41",
            "interface": "Vlan76",
            "mac_address": "7cc2.5527.a974",
            "ports": "Po6"
        },
        {
            "address": "103.110.128.5",
            "device": "42.96.37.41",
            "interface": "Vlan76",
            "mac_address": "7cc2.5527.a9b4",
            "ports": "Po5"
        },
        {
            "address": "103.110.128.7",
            "device": "42.96.37.41",
            "interface": "Vlan76",
            "mac_address": "7cc2.5527.a9cc",
            "ports": "Po7"
        },
        {
            "address": "103.110.128.1",
            "device": "42.96.37.41",
            "interface": "Vlan76",
            "mac_address": "7cc2.5527.a9e8",
            "ports": "Po1"
        },
        {
            "address": "172.16.30.1",
            "device": "42.96.37.41",
            "interface": "Vlan1010",
            "mac_address": "0059.dc66.c1f5",
            "ports": "Vl1010"
        },
        {
            "address": "42.96.37.41",
            "device": "42.96.37.41",
            "interface": "Vlan214",
            "mac_address": "0059.dc66.c1fa",
            "ports": "Vl214"
        },
        {
            "address": "42.96.37.40",
            "device": "42.96.37.41",
            "interface": "Vlan214",
            "mac_address": "84eb.ef5d.461a",
            "ports": "Po100"
        },
        {
            "address": "42.96.37.43",
            "device": "42.96.37.41",
            "interface": "Vlan215",
            "mac_address": "0059.dc66.c1c8",
            "ports": "Vl215"
        },
        {
            "address": "42.96.37.42",
            "device": "42.96.37.41",
            "interface": "Vlan215",
            "mac_address": "f87a.4130.7a6a",
            "ports": "Po100"
        },
        {
            "address": "103.110.128.254",
            "device": "42.96.37.41",
            "interface": "Vlan76",
            "mac_address": "0059.dc66.c1e3",
            "ports": "Vl76"
        },
        {
            "address": "103.110.128.4",
            "device": "42.96.37.41",
            "interface": "Vlan76",
            "mac_address": "7cc2.5527.a594",
            "ports": "Po4"
        }]
    return arp_data

3. Kiểm tra kết quả.

  • Với API http://192.168.13.200:5000/import_all_arp bạn nhận được kết quả như sau:

Postman: Add all arp into database sussess!!!.

Database: Kết quả DB đã được Import ARP từ device.

  • Với API http://192.168.13.200:5000/get_all_arp_from_device bạn nhận được kết quả ARP từ thiết bị.

Với API http://192.168.13.200:5000/get_all_arp_from_db bạn nhận được kết quả từ Database.

  • Với API http://192.168.13.200:5000/get_arp/3 với ID là 3 bạn nhận được kết quả là thông tin dữ liệu có ID là 3.

Hoàn toàn trùng hợp với Database.

Và cuối cùng là API http://192.168.13.200:5000/add_arp.

Kiểm tra trong DB.

Bây giờ nếu bạn thêm lại kết quả sẽ là.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories