NX Lab

Lưu lịch sử chạy script vào SQLite cục bộ: ai chạy, khi nào, kết quả, thời gian (sqlite3 có sẵn)

#Python#Tích hợp#SQLite1 lượt xem

  1. Quản trị viênQuản trị· 0 điểm

    Câu hỏi ·

    CSV đủ cho báo cáo đơn giản, nhưng khi muốn thống kê (script nào hay lỗi, ai dùng nhiều) cơ sở dữ liệu nhỏ như SQLite tiện hơn rất nhiều. Python có sẵn thư viện sqlite3 nên không cần cài thêm gì.

    Lưu lịch sử chạy script vào SQLite cục bộ Lưu lịch sử chạy script vào SQLite cục bộ

    Các bước thực hiện

    1. Tạo bảng. run_log: thời gian, người dùng, script, kết quả, giây.
    2. Ghi mỗi lần chạy. Hàm ghi gọi ở cuối script.
    3. Truy vấn thống kê. Số lần chạy, tỉ lệ lỗi theo script.
    4. Dùng với decorator. Tự ghi kết quả.
    5. Sao lưu. Copy file .db định kỳ.

    Code tham khảo (Python)

    import functools
    import getpass
    import os
    import sqlite3
    import time
    import NXOpen
    
    DB = "D:/NXLab_log/lich_su.db"
    
    def ket_noi():
        os.makedirs(os.path.dirname(DB), exist_ok=True)
        conn = sqlite3.connect(DB, timeout=10)
        conn.execute("""CREATE TABLE IF NOT EXISTS run_log (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            thoi_gian TEXT, nguoi_dung TEXT, script TEXT, part TEXT, ket_qua TEXT, giay REAL, ghi_chu TEXT)""")
        return conn
    
    def ghi(script, part, ket_qua, giay, ghi_chu=""):
        conn = ket_noi()
        try:
            with conn:
                conn.execute("INSERT INTO run_log (thoi_gian, nguoi_dung, script, part, ket_qua, giay, ghi_chu) VALUES (?,?,?,?,?,?,?)",
                             (time.strftime("%Y-%m-%d %H:%M:%S"), getpass.getuser(), script, part, ket_qua, giay, ghi_chu))
        finally:
            conn.close()
    
    def co_lich_su(ten_script):
        def trang_tri(ham):
            @functools.wraps(ham)
            def boc(*a, **kw):
                t0 = time.perf_counter()
                part = NXOpen.Session.GetSession().Parts.Work
                ten_part = part.Leaf if part else ""
                try:
                    kq = ham(*a, **kw)
                    ghi(ten_script, ten_part, "OK", time.perf_counter() - t0)
                    return kq
                except Exception as ex:
                    ghi(ten_script, ten_part, "LOI", time.perf_counter() - t0, str(ex))
                    raise
            return boc
        return trang_tri
    
    def thong_ke():
        conn = ket_noi()
        try:
            return conn.execute("""SELECT script, COUNT(*), SUM(ket_qua='LOI'), ROUND(AVG(giay),2)
                                   FROM run_log GROUP BY script ORDER BY COUNT(*) DESC""").fetchall()
        finally:
            conn.close()
    
    @co_lich_su("kiem_tra_demo")
    def chay_demo():
        time.sleep(0.2)
    
    def main():
        lw = NXOpen.Session.GetSession().ListingWindow
        lw.Open()
        chay_demo()
        lw.WriteLine("%-24s %6s %6s %8s" % ("Script", "Lần", "Lỗi", "TB giây"))
        for ten, n, loi, tb in thong_ke():
            lw.WriteLine("%-24s %6d %6d %8.2f" % (ten[:24], n, loi or 0, tb))
    
    if __name__ == "__main__":
        main()
    

    Giải thích code

    • Câu lệnh SQL dùng tham số ? thay vì ghép chuỗi để tránh lỗi và chèn SQL.
    • with conn: tự commit khi thành công hoặc rollback khi lỗi.
    • Decorator co_lich_su bọc script để tự ghi OK/LOI và thời gian mà không phải sửa nội dung script.

    Lỗi thường gặp

    • SQLite trên ổ mạng có nhiều người ghi đồng thời dễ khóa file; dùng file cục bộ hoặc CSDL máy chủ cho nhóm lớn.
    • Không ghi dữ liệu nhạy cảm (nội dung bản vẽ khách hàng) vào bảng lịch sử.

    Code mang tính tham khảo, viết cho NX 12 trở lên (Python journal). Tên menu và một số lớp có thể khác theo phiên bản NX; hãy chạy thử trên bản sao của chi tiết trước khi dùng cho dữ liệu thật.

    Điểm: 0

Trả lời

Đăng nhập để tham gia thảo luận.