# Thêm thư mục gốc vào sys.path import os,sys sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))) from function.prompt import prompt_selling as prompt_selling from langchain_core.prompts.prompt import PromptTemplate PROMPT_SUFFIX = """Only use the following tables: {table_info} Question: {input} """ _DEFAULT_TEMPLATE = """ Instructions for Generating SQL Queries in Python (PyMySQL-Compatible) Purpose: Given a user input question, generate a syntactically correct SQL query with strict role enforcement, deletion restrictions, and data integrity checks. ==================================================== Role-Based Security & Enforcement (Mandatory) ==================================================== 1. **Role Validation**: - Before generating any SQL query, validate the user's role and permissions. - If the user’s role is unauthorized for the requested operation: → Return an error: "ERROR: Unauthorized operation for role." → DO NOT generate or execute any SQL query. 2. **Table-Specific Rule Enforcement**: - If the requested operation violates specific table rules (e.g., attempt to delete restricted data): → Return an error: "ERROR: Operation not permitted on this table." → DO NOT generate or execute any SQL query. ==================================================== Deletion Restriction (No DELETE Allowed) ==================================================== - Deletion operations are strictly prohibited. - Instead of DELETE: → Use UPDATE to set: `isdeleted = TRUE`, `deletion_date = CURRENT_TIMESTAMP` - Restoration: → UPDATE to set: `isdeleted = FALSE`, `deletion_date = NULL` ==================================================== Data Integrity Requirements ==================================================== 3. **Required Fields for INSERT/UPDATE**: - Always include: `creation_date`, `update_date`, `isdeleted` 4. **Schema Adherence**: - Use only explicitly provided column names from schema. - Never assume or guess column names. - Wrap all table and column names with backticks (`). 5. **SELECT Queries**: - Do NOT use `SELECT *`. - Specify only the necessary columns. 6. **Formatting & Readability**: - Ensure clean, readable formatting for SQL queries. 7. **Invalid Operation Handling**: - If an operation is invalid or not allowed: → Return: "ERROR: Invalid or unauthorized operation." 8. **ID Columns**: - Never show or include the following IDs in the output: → product, category, post, orders, shipment, payment IDs. 9. **Current Year**: - Always use current year as 2025. ==================================================== Safe UPDATE Query Execution ==================================================== 10. **Avoid Subquery Errors**: - Never use subqueries in the WHERE clause that return multiple rows. - Store result in a variable first, then use it in the UPDATE WHERE clause. ✅ Example: ```sql -- WRONG: UPDATE `product_translation` SET `pro_name` = 'Pink guava leaf tea' WHERE `pro_id` = (SELECT `pro_id` FROM `product` WHERE `pro_name` = 'Trà ổi lá hồng'); -- CORRECT: SET @pro_id_var = (SELECT `pro_id` FROM `product` WHERE `pro_name` = 'Trà ổi lá hồng' LIMIT 1); UPDATE `product_translation` SET `pro_name` = 'Pink guava leaf tea' WHERE `pro_id` = @pro_id_var; ``` ==================================================== Category Duplication Prevention (CRITICAL) ==================================================== ⚠️ Before INSERT or UPDATE on `category` table: - Prevent duplicate `cate_name` (translated to Vietnamese if needed). ✅ For INSERT: 1. If language is Vietnamese, check directly in `category`. 2. If language is English: → Translate `cate_name` to Vietnamese. → Check for duplicate in `category`. 3. If duplicate exists: → Return error: "DUPLICATE_CATEGORY_NAME" → DO NOT execute INSERT. ✅ For UPDATE: 1. Translate `cate_name` to Vietnamese if needed. 2. Check if any record (excluding current) has the same `cate_name`. 3. If duplicate exists: → Return error: "DUPLICATE_CATEGORY_NAME" → DO NOT execute UPDATE. 🚨 Validation must occur within SQL execution (no pre-checks or separate queries allowed). ==================================================== Output Format for Each Query ==================================================== Question: SQLQuery: SQLResult: Answer: """ from function.gemini_response import get_table from function.prompt import personalization import importlib import os import pkgutil from function.prompt.table import users,review,user_voucher,user_coin,orders_orderitem,cart_cartItem,category_categoryTranslation,product,post_postTranslation,shipment,favourite,absence,payments_shipment_group,group_order_members,group_orders,cart_cartitem_group,shipper_attendance,shipper_commission_detail,shipper_salary_summary from function.prompt import prompt_detail_table async def return_table(query): data = await get_table.response_general(query) print(data) text = "" text_schema = "" grouped_data = {} table_mapping = { "user": ["user"], "absence": ["absence"], "cart_group":["cart_group","cart_item_group"], "group_order":["group_orders","payments_group"], "group_order_member":["group_order_members"], "user_voucher": ["user_voucher"], "category": ["category", "category_translation"], "cart": ["cart", "cart_item"], "orders": ["orders", "order_item", "payment"], "favourite": ["favourite", "favourite_item"], "post": ["post", "post_translation"], "product": ["product", "product_translation"], "shipment": ["shipment"], "shipment_group": ["shipment_group"], "shipper_attendance":["shipper_attendance"], "shipper_commission_detail" : ["shipper_commission_detail"], "shipper_salary_summary": ["shipper_salary_summary"], "review": ["review"], "user_coin": ["user_coin"], } content_mapping = { "user": users.prompt_user, "user_voucher": user_voucher.prompt_user_voucher, "category": category_categoryTranslation.prompt_category_management, "cart": cart_cartItem.prompt_cart_management, "cart_group": cart_cartitem_group.prompt_cart_group_management , "orders": orders_orderitem.prompt, "favourite": favourite.prompt_favourite_management, "post": post_postTranslation.prompt_post_management, "product": product.prompt_product_management, "shipment": shipment.prompt_shipment, "review": review.prompt_review, "user_coin": user_coin.prompt_user_coint, "shipper_salary_summary": shipper_salary_summary.prompt_commission_management, "shipper_commission_detail": shipper_commission_detail.prompt_commission_management, "shipper_attendance": shipper_attendance.prompt_shipper_attendance_management, "shipment_group": payments_shipment_group.prompt_shipment, "group_order_member": group_order_members.prompt_shipper_attendance_management, "group_order": group_orders.prompt, "absence": absence.prompt_absence_management, } # Mapping bảng -> hàm lấy schema riêng biệt schema_mapping = { "user": prompt_detail_table.prompt_users, "user_voucher": prompt_detail_table.prompt_user_voucher, "category": prompt_detail_table.prompt_categort, "category_translation": prompt_detail_table.prompt_category_translation, "cart": prompt_detail_table.prompt_cart, "cart_item": prompt_detail_table.prompt_cart_item, "orders":prompt_detail_table.prompt_orders, "order_item": prompt_detail_table.prompt_order_item, "payment": prompt_detail_table.prompt_payments, "favourite": prompt_detail_table.prompt_favourite, "favourite_item": prompt_detail_table.prompt_fav_item, "post": prompt_detail_table.prompt_post, "post_translation": prompt_detail_table.prompt_post_translation, "product": prompt_detail_table.prompt_product, "product_translation": prompt_detail_table.prompt_product_translation, "shipment": prompt_detail_table.prompt_shipment, "product_variants": prompt_detail_table.prompt_product_variants, "review": prompt_detail_table.prompt_review, "user_coin": prompt_detail_table.prompt_user_coin, "absence": prompt_detail_table.prompt_absence, "cart_group": prompt_detail_table.prompt_cart_group, "cart_item_group": prompt_detail_table.prompt_cartitem_group, "group_orders": prompt_detail_table.prompt_group_orders, "payments_group": prompt_detail_table.prompt_payments_group, "group_order_members":prompt_detail_table.prompt_group_orders_member, "shipment_group":prompt_detail_table.prompt_shipment_group, "shipper_attendance":prompt_detail_table.prompt_shipper_attendance, "shipper_commission_detail":prompt_detail_table.prompt_shipper_commission_detail, "shipper_salary_summary":prompt_detail_table.prompt_shipper_salary_summary } # Gom nội dung prompt theo nhóm for value in data: for key, tables in table_mapping.items(): if value in tables: grouped_data[key] = content_mapping[key] break # Ghép nội dung prompt for idx, (table_name, content) in enumerate(grouped_data.items(), start=1): text += f"{idx}. {table_name}:\n{content}\n\n" # Lấy schema riêng cho từng bảng for idx, table_name in enumerate(data, start=1): schema_text = schema_mapping.get(table_name) if schema_text: text_schema += f"{idx}. Bảng: {table_name}\n{schema_text}\n\n" else: text_schema += f"{idx}. Bảng: {table_name}\nKhông tìm thấy schema.\n\n" return text, text_schema from function.prompt import general_rule from function.prompt import prompt_table,personalization async def get_prompt_custom(query): text, text_schema = await return_table(query) _ROLE_TEMPLATE = f""" **Roles and their associated permissions are central to ensuring secure, organized, and efficient database operations. Pay special attention to role-based rules and table-specific restrictions when constructing SQL queries: {text}. \n **General Rule:** {general_rule.prompt_rule}. ** Vui lòng xem thêm mô tả các bảng dưới đây để xác định chính xác câu lệnh SQL cần dùng và phải hợp lý: {text_schema}. - Không dùng % hoặc format() để "nhét" trực tiếp biến vào câu SQL. - **Tuyệt đối Cấm dùng "%%s" để lấy giá trị từ biến** - ** Hãy luôn luôn tránh lỗi cú pháp SQL khi trả về cho mình.** - "- Tránh các lỗi như :\n" " (1054, \"Unknown column 'oi.pro_id' in 'field list'\")\n . Luôn đảm bảo bạn không bao giờ bị lỗi này" " (1054, \"Unknown column 'oi.note' in 'field list'\") . Luôn đảm bảo bạn không bao giờ bị lỗi này\n" " (1054, \"Unknown column 'oi.size' in 'field list'\") . Luôn đảm bảo bạn không bao giờ bị lỗi này \n" " (1054, \"Unknown column 'c.is_deleted' in 'on clause'\"). Luôn đảm bảo bạn không bao giờ bị lỗi này\n" Tham khảo thêm prompt cá nhân hóa: - {personalization.prompt} Tuyệt đối không trả về câu SQL nằm trong [],list điều này bị cấm tuyệt đối """ PROMPT = PromptTemplate( input_variables=["input", "table_info", "dialect", "top_k", "role","language"], template=_ROLE_TEMPLATE + _DEFAULT_TEMPLATE + PROMPT_SUFFIX ) return PROMPT import asyncio # print(asyncio.run(return_table("Liệt kê các voucher mà người dùng có user_id là 5 đang sở hữu")))