Programming Basics SQL HTML CSS JavaScript React Python C++ Java JavaFX Swing Problem Solving English English Conversations Computer Fundamentals Linux Learn Typing

طريقة إنشاء نسخة إحتياطية من قاعدة بيانات MySQL و استرجاع النسخة الإحتياطية في بايثون؟

عملت بقاعدة بيانات SQLite3 لكن لم أستطع تأمينها. و أعتقد أن MySQL آمنة.

المشكلة أنني عندما أريد عمل نسخة إحتياطية من أجل نسخ كل البيانات الموجودة فيها و أنقلها لجهاز آخر كتحديث لقاعدة البيانات.

عند محاولة إسترجاع البيانات من نسخة موجودة تظهر لي المشكلة كالتالي:

1136 (21S01): Column count doesn't match value count at row 1

كود إسترجاع النسخة:

def restore_database(self):
    # Encryption key
    key = b'wWU9Yh3Q7JN5XXpbK43YuMYQtA9yUI3wdDzmADMUOzk=wq'

    # Initialize the Fernet cipher with the key
    cipher = Fernet(key)
    try:
        conn = mysql.connector.connect(
            host="localhost",
            user="root",
            password=self.hashed_password1,
            database="color_group"
        )
        c = conn.cursor()
        c.execute("CREATE DATABASE IF NOT EXISTS color_group")
        c.execute("USE color_group")
        # Define the table structure without the image column
        table_structure = """CREATE TABLE IF NOT EXISTS color_numbers (
                                               id INTEGER PRIMARY KEY AUTO_INCREMENT,
                                               id_name varchar(255),
                                               ingred1 varchar(255),
                                               ingred2 varchar(255),
                                               ingred3 varchar(255),
                                               ingred4 varchar(255),
                                               ingred5 varchar(255),
                                               ingred6 varchar(255),
                                               ingred7 varchar(255),
                                               ingred8 varchar(255),
                                               ingred9 varchar(255),
                                               info1 varchar(255),
                                               info2 varchar(255),
                                               info3 varchar(255),
                                               info4 varchar(255),
                                               info5 varchar(255),
                                               info6 varchar(255),
                                               info7 varchar(255),
                                               info8 varchar(255),
                                               info9 varchar(255),
                                               quantity_no1 float,
                                               quantity_no2 float,
                                               quantity_no3 float,
                                               quantity_no4 float,
                                               quantity_no5 float,
                                               quantity_no6 float,
                                               quantity_no7 float,
                                               quantity_no8 float,
                                               quantity_no9 float,
                                               puplic_name varchar(255),
                                               client1 varchar(255),
                                               client2 varchar(255),
                                               client3 varchar(255),
                                               client4 varchar(255),
                                               client5 varchar(255),
                                               client6 varchar(255),
                                               image LONGBLOB,
                                               word VARCHAR(255),
                                               tof TINYINT,
                                               colorid VARCHAR(255)
                                           )"""

        backup_file_path = filedialog.askopenfilename()  # Prompt user to select a database file
        if backup_file_path:
            c.execute("DROP TABLE IF EXISTS color_numbers")
            c.execute(table_structure)
            with open(backup_file_path, "rb") as backup_file:
                encrypted_data = backup_file.read()

                # Decrypt the data
                decrypted_data = cipher.decrypt(encrypted_data).decode('"ISO-8859-1"')

                # Remove the image column from the SQL commands
                sql_commands = re.sub(r'`image` LONGBLOB,?', '', decrypted_data)
                sql_commands = sql_commands.split(';')

                for command in sql_commands:
                    if command.strip() and "INSERT INTO color_numbers" in command:
                        c.execute(command)
            c.execute("ALTER USER 'root'@'localhost' IDENTIFIED BY %s", (self.hashed_password1,))
            c.execute("update color_numbers set tof = 0")
        else:
            self.create_database()
            return

        conn.commit()
        c.close()
        conn.close()
        msg.showinfo("قاعدة البيانات", " تم استعادة قاعدة البيانات بنجاح. سيتم الخروج الان")
        self.on_closing()
    except Exception as e:
        msg.showerror("خطأ", f"{e}")
        print(e)

سؤال ثاني

مستقبلاً لو أردت إضافة COLUMN جديد و عملت نسخة جديدة من أجل تحديث قاعدة البيانات فهل سيستقبل التحديث الجديد أم سيظهر لي أخطاء جديدة؟

أنا أستخدم تشفير Fernet من أجل تشفير ملف المنشئ من النسخة.

كود إنشاء النسخة: الكود التالي يعمل نسخة إحتياطية، أولاً ينشئ ملف إمتداده .sql غير مشفر بعدها يشفر هذا الملف بصيغة .enc و بعدها يحذف الملف الغير مشفر نهائياً.

def create_copy_of_database(self):
    try:
        conn = self.connect_to_database()
        cursor = conn.cursor()

        # Prompt the user to select a backup location
        backup_folder = filedialog.askdirectory()
        if backup_folder:  # Ensure a folder was selected
            # Generate backup file name with timestamp
            backup_file_name = f"Database_Backup_{datetime.now().strftime('%Y-%m-%d_%H-%S')}.sql"
            backup_location = os.path.join(backup_folder, backup_file_name)

            # Creating backup file
            with open(backup_location, "w") as backup_file:
                # rest of the function remains the same
                cursor.execute("SHOW TABLES")
                tables = cursor.fetchall()
                for table in tables:
                    table_name = table[0]
                    cursor.execute(f"SELECT * FROM {table_name}")
                    rows = cursor.fetchall()
                    backup_file.write(f"\n-- Table structure for table {table_name}\n")
                    cursor.execute(f"SHOW CREATE TABLE {table_name}")
                    create_table = cursor.fetchone()[1]
                    backup_file.write(f"{create_table};\n")

                    backup_file.write(f"\n-- Data for table {table_name}\n")
                    for row in rows:
                        values = []
                        for value in row:
                            if isinstance(value, str):
                                values.append(f"'{value}'")
                            elif isinstance(value, bytes):
                                values.append(f"x'{value.hex()}'")
                            elif value is None:
                                values.append("NULL")
                            elif isinstance(value, float):
                                values.append(repr(value))
                            else:
                                values.append(str(value))
                        insert_query = f"INSERT INTO {table_name} VALUES ({', '.join(values)});\n"
                        backup_file.write(insert_query)

            # Perform encryption
            encryption_key = b'wWU9Yh3Q7JN5XXpbK43YuMYQtA9yUI3wdDzmADMUOzk=wq'  # Encryption key
            with open(backup_location, 'rb') as f:
                data = f.read()
            fernet = Fernet(encryption_key)
            encrypted_data = fernet.encrypt(data)
            encrypted_backup_file_name = f"Encrypted_Database_Backup_{datetime.now().strftime('%Y-%m-%d_%H-%S')}.enc"
            encrypted_backup_location = os.path.join(backup_folder, encrypted_backup_file_name)
            with open(encrypted_backup_location, 'wb') as f:
                f.write(encrypted_data)

            os.unlink(backup_location)  # Permanently delete the unencrypted .sql file

            cursor.close()
            conn.close()
            msg.showinfo("Success", "تمت العملية بنجاح.")
            os.startfile(backup_folder)

        else:
            self.general_manager()
            return

    except Exception as e:
        msg.showerror("خطأ في إجراء العملية", f"{e}")

إذا أحد عنده فكرة حول تشفير الملف قبل حفظه، و ليس حفظه كملف غير مشفر و بعدها يتم تشفيره ثم يتم حذفه، أتمنى ذكرها.

إن شاء الله وصلت الفكرة.

تعليقات 3

أضف تعليق

يجب تسجيل الدخول حتى تتمكن من إضافة تعليق أو رد.