{"id":919,"date":"2026-10-29T18:18:22","date_gmt":"2026-10-29T15:18:22","guid":{"rendered":"https:\/\/keefwiki.com\/code\/?p=919"},"modified":"2026-10-29T18:18:23","modified_gmt":"2026-10-29T15:18:23","slug":"sqlite-python-safe-database-migration","status":"publish","type":"post","link":"https:\/\/keefwiki.com\/code\/2026\/10\/29\/sqlite-python-safe-database-migration\/","title":{"rendered":"\u0643\u064a\u0641\u064a\u0629 \u062a\u0631\u062d\u064a\u0644 \u0642\u0627\u0639\u062f\u0629 SQLite \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Python \u062f\u0648\u0646 \u0641\u0642\u062f \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a"},"content":{"rendered":"<p class=\"wp-block-paragraph\">\u062a\u062d\u062a\u0627\u062c \u062a\u0631\u062d\u064a\u0644 \u0642\u0627\u0639\u062f\u0629 SQLite \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Python \u0639\u0646\u062f\u0645\u0627 \u062a\u063a\u064a\u0651\u0631 \u0628\u0646\u064a\u0629 \u062c\u062f\u0648\u0644 \u0645\u0648\u062c\u0648\u062f \u0641\u064a \u062a\u0637\u0628\u064a\u0642 \u0641\u0639\u0644\u064a. \u0646\u062c\u0627\u062d \u0623\u0645\u0631 ALTER TABLE \u0648\u062d\u062f\u0647 \u0644\u0627 \u064a\u0636\u0645\u0646 \u0633\u0644\u0627\u0645\u0629 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a\u061b \u0644\u0630\u0644\u0643 \u0627\u062c\u0645\u0639 \u0628\u064a\u0646 \u0627\u0644\u0646\u0633\u062e\u0629 \u0627\u0644\u0627\u062d\u062a\u064a\u0627\u0637\u064a\u0629 \u0648\u0627\u0644\u0645\u0639\u0627\u0645\u0644\u0629 \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0644\u0646\u062a\u0627\u0626\u062c \u0648\u062e\u0637\u0629 \u0627\u0633\u062a\u0631\u062c\u0627\u0639 \u0645\u062c\u0631\u0628\u0629.<\/p>\n\n<h2 class=\"wp-block-heading\">\u0642\u0628\u0644 \u062a\u0631\u062d\u064a\u0644 \u0642\u0627\u0639\u062f\u0629 SQLite \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Python<\/h2>\n\n<p class=\"wp-block-paragraph\">\u0627\u0639\u0645\u0644 \u0639\u0644\u0649 \u0646\u0633\u062e\u0629 \u062a\u062c\u0631\u064a\u0628\u064a\u0629 \u0645\u0646 \u0642\u0627\u0639\u062f\u0629 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a\u060c \u062b\u0645 \u0623\u0648\u0642\u0641 \u0639\u0645\u0644\u064a\u0627\u062a \u0627\u0644\u0643\u062a\u0627\u0628\u0629 \u0623\u062b\u0646\u0627\u0621 \u0627\u0644\u062a\u062d\u062f\u064a\u062b \u0627\u0644\u0625\u0646\u062a\u0627\u062c\u064a. \u0627\u062d\u062a\u0641\u0638 \u0628\u0646\u0633\u062e\u0629 \u0627\u062d\u062a\u064a\u0627\u0637\u064a\u0629 \u0645\u062a\u0633\u0642\u0629 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 SQLite Backup API\u060c \u0644\u0627 \u0628\u0646\u0633\u062e \u0627\u0644\u0645\u0644\u0641 \u0639\u0634\u0648\u0627\u0626\u064a\u064b\u0627 \u0623\u062b\u0646\u0627\u0621 \u0627\u0644\u0643\u062a\u0627\u0628\u0629. \u0648\u062a\u0623\u0643\u062f \u0645\u0646 \u0625\u0635\u062f\u0627\u0631 SQLite \u0627\u0644\u0641\u0639\u0644\u064a \u0627\u0644\u0630\u064a \u062a\u0633\u062a\u062e\u062f\u0645\u0647 \u0645\u0643\u062a\u0628\u0629 Python.<\/p>\n\n<h2 class=\"wp-block-heading\">\u0645\u062b\u0627\u0644 \u0625\u0636\u0627\u0641\u0629 \u0639\u0645\u0648\u062f \u0627\u062e\u062a\u064a\u0627\u0631\u064a \u0628\u0637\u0631\u064a\u0642\u0629 \u0622\u0645\u0646\u0629<\/h2>\n\n<pre class=\"wp-block-code\"><code class=\"language-python\">import sqlite3\nfrom pathlib import Path\nfrom contextlib import closing\nfrom datetime import datetime, timezone\n\npath = Path(&#039;app.db&#039;)\nif not path.is_file():\n    raise FileNotFoundError(&#039;app.db not found&#039;)\nbackup_path = Path(f&#039;app-{datetime.now(timezone.utc):%Y%m%d-%H%M%S-%f}.backup.db&#039;)\n\nwith closing(sqlite3.connect(path)) as source:\n    with closing(sqlite3.connect(backup_path)) as backup:\n        source.backup(backup)\n\nwith closing(sqlite3.connect(path)) as db:\n    try:\n        db.execute(&#039;BEGIN IMMEDIATE&#039;)\n        old_count = db.execute(&#039;SELECT COUNT(*) FROM customers&#039;).fetchone()[0]\n        cols = {row[1] for row in db.execute(&#039;PRAGMA table_info(customers)&#039;)}\n        if &#039;phone&#039; not in cols:\n            db.execute(&#039;ALTER TABLE customers ADD COLUMN phone TEXT&#039;)\n        new_count = db.execute(&#039;SELECT COUNT(*) FROM customers&#039;).fetchone()[0]\n        if old_count != new_count:\n            raise RuntimeError(&#039;Row count changed&#039;)\n        if db.execute(&#039;PRAGMA integrity_check&#039;).fetchone()[0] != &#039;ok&#039;:\n            raise RuntimeError(&#039;Integrity check failed&#039;)\n        if db.execute(&#039;PRAGMA foreign_key_check&#039;).fetchall():\n            raise RuntimeError(&#039;Foreign-key check failed&#039;)\n        db.commit()\n    except Exception:\n        db.rollback()\n        raise\nprint(&#039;Migration completed; backup:&#039;, backup_path)<\/code><\/pre>\n\n<p class=\"wp-block-paragraph\">\u064a\u0641\u062a\u0631\u0636 \u0627\u0644\u0645\u062b\u0627\u0644 \u0648\u062c\u0648\u062f \u062c\u062f\u0648\u0644 customers\u061b \u0627\u0633\u062a\u0628\u062f\u0644\u0647 \u0628\u062c\u062f\u0648\u0644 \u0645\u0634\u0631\u0648\u0639\u0643. \u064a\u0646\u0634\u0626 \u0645\u0644\u0641 \u0646\u0633\u062e\u0629 \u0627\u062d\u062a\u064a\u0627\u0637\u064a\u0629 \u0645\u0633\u062a\u0642\u0644\u064b\u0627 \u0641\u064a \u0643\u0644 \u062a\u0634\u063a\u064a\u0644 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u062a\u0648\u0642\u064a\u062a UTC\u060c \u062b\u0645 \u064a\u0636\u064a\u0641 \u0627\u0644\u0639\u0645\u0648\u062f phone \u0625\u0646 \u0644\u0645 \u064a\u0643\u0646 \u0645\u0648\u062c\u0648\u062f\u064b\u0627. \u0642\u0628\u0644 \u0627\u0644\u0627\u0644\u062a\u0632\u0627\u0645 \u0628\u0627\u0644\u0645\u0639\u0627\u0645\u0644\u0629\u060c \u064a\u0642\u0627\u0631\u0646 \u0639\u062f\u062f \u0627\u0644\u0635\u0641\u0648\u0641 \u0648\u064a\u0641\u062d\u0635 \u0633\u0644\u0627\u0645\u0629 \u0642\u0627\u0639\u062f\u0629 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0648\u0627\u0644\u0639\u0644\u0627\u0642\u0627\u062a \u0627\u0644\u0645\u0631\u062c\u0639\u064a\u0629. \u0648\u0642\u062f \u062a\u062e\u062a\u0644\u0641 \u0637\u0631\u064a\u0642\u0629 \u0627\u0644\u062a\u0631\u062d\u064a\u0644 \u0639\u0646\u062f \u0625\u0639\u0627\u062f\u0629 \u0628\u0646\u0627\u0621 \u062c\u062f\u0648\u0644 \u0623\u0648 \u062a\u063a\u064a\u064a\u0631 \u0642\u064a\u062f \u0645\u0648\u062c\u0648\u062f.<\/p>\n\n<h2 class=\"wp-block-heading\">\u0643\u064a\u0641\u064a\u0629 \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0642\u0628\u0644 \u0627\u0644\u062a\u0631\u062d\u064a\u0644 \u0648\u0628\u0639\u062f\u0647<\/h2>\n\n<ol class=\"wp-block-list\"><li>\u0623\u0646\u0634\u0626 \u0642\u0627\u0639\u062f\u0629 \u062a\u062c\u0631\u064a\u0628\u064a\u0629 \u0641\u064a\u0647\u0627 \u062c\u062f\u0648\u0644 customers \u0648\u0633\u062c\u0644\u0627\u062a \u0645\u0639\u0631\u0648\u0641\u0629\u060c \u062b\u0645 \u0627\u062d\u0633\u0628 \u0627\u0644\u0635\u0641\u0648\u0641 \u0648\u0633\u062c\u0651\u0644 \u0646\u0633\u062e\u0629 \u0645\u0646 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0623\u0633\u0627\u0633\u064a\u0629.<\/li><li>\u0627\u062d\u0641\u0638 \u0627\u0644\u0643\u0648\u062f \u0628\u0627\u0633\u0645 migrate.py \u0641\u064a \u0645\u062c\u0644\u062f \u0642\u0627\u0639\u062f\u0629 app.db\u060c \u0648\u0634\u063a\u0651\u0644\u0647 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 python migrate.py. \u0644\u0627 \u062a\u0634\u063a\u0651\u0644\u0647 \u0639\u0644\u0649 \u0642\u0627\u0639\u062f\u0629 \u0625\u0646\u062a\u0627\u062c\u064a\u0629 \u0642\u0628\u0644 \u0627\u062e\u062a\u0628\u0627\u0631 \u0627\u0633\u062a\u0639\u0627\u062f\u0629 \u0627\u0644\u0646\u0633\u062e\u0629 \u0627\u0644\u0627\u062d\u062a\u064a\u0627\u0637\u064a\u0629.<\/li><li>\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0633\u0645 \u0645\u0644\u0641 \u0627\u0644\u0646\u0633\u062e\u0629 \u0627\u0644\u0627\u062d\u062a\u064a\u0627\u0637\u064a\u0629\u060c \u0648\u0645\u0646 \u0648\u062c\u0648\u062f \u0627\u0644\u0639\u0645\u0648\u062f phone \u0648\u0628\u0642\u0627\u0621 \u0627\u0644\u0633\u062c\u0644\u0627\u062a \u0643\u0645\u0627 \u0647\u064a\u060c \u0648\u0634\u063a\u0651\u0644 PRAGMA integrity_check \u0648 PRAGMA foreign_key_check.<\/li><li>\u0634\u063a\u0651\u0644 \u0627\u0644\u0628\u0631\u0646\u0627\u0645\u062c \u062b\u0627\u0646\u064a\u0629\u064b \u0639\u0644\u0649 \u0646\u0633\u062e\u0629 \u062a\u062c\u0631\u064a\u0628\u064a\u0629 \u0644\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0639\u062f\u0645 \u0645\u062d\u0627\u0648\u0644\u0629 \u0625\u0636\u0627\u0641\u0629 \u0627\u0644\u0639\u0645\u0648\u062f \u0646\u0641\u0633\u0647\u060c \u062b\u0645 \u0634\u063a\u0651\u0644 \u0627\u062e\u062a\u0628\u0627\u0631\u0627\u062a \u0627\u0644\u062a\u0637\u0628\u064a\u0642 \u0627\u0644\u062a\u064a \u062a\u0633\u062a\u062e\u062f\u0645 \u0627\u0644\u0628\u0646\u064a\u0629 \u0627\u0644\u062c\u062f\u064a\u062f\u0629.<\/li><li>\u0625\u0630\u0627 \u0641\u0634\u0644\u062a \u0627\u062e\u062a\u0628\u0627\u0631\u0627\u062a \u0627\u0644\u062a\u0637\u0628\u064a\u0642 \u0628\u0639\u062f \u0627\u0644\u062a\u0631\u062d\u064a\u0644\u060c \u0623\u0648\u0642\u0641 \u0627\u0644\u0643\u062a\u0627\u0628\u0629 \u0623\u0648\u0644\u064b\u0627 \u062b\u0645 \u0642\u064a\u0651\u0645 \u0627\u0644\u0627\u0633\u062a\u0639\u0627\u062f\u0629 \u0648\u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0623\u062d\u062f\u062b \u0645\u0646 \u062a\u0627\u0631\u064a\u062e \u0627\u0644\u0646\u0633\u062e\u0629 \u0627\u0644\u0627\u062d\u062a\u064a\u0627\u0637\u064a\u0629.<\/li><\/ol>\n\n<h2 class=\"wp-block-heading\">\u0645\u0627\u0630\u0627 \u0644\u0648 \u0623\u0631\u062f\u062a \u062a\u0639\u062f\u064a\u0644 \u0642\u064a\u0648\u062f \u0627\u0644\u0639\u0645\u0648\u062f \u0623\u0648 \u0646\u0648\u0639\u0647<\/h2>\n\n<p class=\"wp-block-paragraph\">\u0644\u0627 \u064a\u062f\u0639\u0645 ALTER TABLE \u0641\u064a SQLite \u0643\u0644 \u062a\u063a\u064a\u064a\u0631\u0627\u062a \u0627\u0644\u0628\u0646\u064a\u0629 \u0645\u0628\u0627\u0634\u0631\u0629. \u0642\u062f \u062a\u062d\u062a\u0627\u062c \u0625\u0644\u0649 \u0628\u0646\u0627\u0621 \u062c\u062f\u0648\u0644 \u062c\u062f\u064a\u062f \u062b\u0645 \u0646\u0642\u0644 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0648\u0625\u0639\u0627\u062f\u0629 \u0625\u0646\u0634\u0627\u0621 \u0627\u0644\u0641\u0647\u0627\u0631\u0633 \u0648\u0627\u0644\u0645\u062d\u0641\u0632\u0627\u062a \u0648\u0627\u0644\u0639\u0631\u0648\u0636\u060c \u0645\u0639 \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0644\u0642\u064a\u0648\u062f. \u0627\u0642\u0631\u0623 \u0627\u0644\u0625\u062c\u0631\u0627\u0621 \u0627\u0644\u0631\u0633\u0645\u064a \u0643\u0627\u0645\u0644\u064b\u0627 \u0642\u0628\u0644 \u0627\u0644\u0646\u0642\u0644\u061b \u0641\u062a\u0639\u0637\u064a\u0644 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0623\u062c\u0646\u0628\u064a\u0629 \u0623\u0648 \u0625\u0633\u0642\u0627\u0637 \u062c\u062f\u0648\u0644 \u062f\u0648\u0646 \u062e\u0637\u0629 \u0642\u062f \u064a\u0633\u0628\u0628 \u062e\u0633\u0627\u0626\u0631.<\/p>\n\n<h2 class=\"wp-block-heading\">\u0643\u064a\u0641 \u062a\u062a\u0631\u0627\u062c\u0639 \u0639\u0646 \u062a\u0631\u062d\u064a\u0644 \u0641\u0627\u0634\u0644<\/h2>\n\n<p class=\"wp-block-paragraph\">\u0625\u0630\u0627 \u0648\u0642\u0639 \u0627\u0644\u062e\u0637\u0623 \u062f\u0627\u062e\u0644 \u0645\u0639\u0627\u0645\u0644\u0629 \u0644\u0645 \u062a\u0644\u062a\u0632\u0645 \u0628\u0647\u0627 \u0628\u0639\u062f\u060c \u0646\u0641\u0651\u0630 rollback. \u0623\u0645\u0627 \u0625\u0630\u0627 \u0627\u0644\u062a\u0632\u0645\u062a \u0628\u0627\u0644\u062a\u0631\u062d\u064a\u0644 \u062b\u0645 \u0627\u0643\u062a\u0634\u0641\u062a \u062e\u0644\u0644\u064b\u0627\u060c \u0641\u0644\u0627 \u062a\u0641\u062a\u0631\u0636 \u0623\u0646 \u0627\u0644\u062a\u0631\u0627\u062c\u0639 \u0639\u0646 \u0627\u0644\u0645\u062e\u0637\u0637 \u0648\u062d\u062f\u0647 \u064a\u0639\u064a\u062f \u0643\u0644 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a\u061b \u0623\u0648\u0642\u0641 \u0627\u0644\u0643\u062a\u0627\u0628\u0629 \u0648\u0627\u0633\u062a\u0631\u062c\u0639 \u0627\u0644\u0646\u0633\u062e\u0629 \u0627\u0644\u0633\u0644\u064a\u0645\u0629 \u0628\u0639\u062f \u062d\u0633\u0627\u0628 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u062a\u064a \u0638\u0647\u0631\u062a \u0645\u0646\u0630 \u0623\u062e\u0630\u0647\u0627.<\/p>\n\n<p class=\"wp-block-paragraph\">\u0627\u062d\u062a\u0641\u0638 \u0628\u0633\u062c\u0644 \u0625\u0635\u062f\u0627\u0631 \u0644\u0644\u0645\u062e\u0637\u0637 \u0648\u0646\u0633\u062e\u0629 \u0627\u062d\u062a\u064a\u0627\u0637\u064a\u0629 \u0642\u0627\u0628\u0644\u0629 \u0644\u0644\u0627\u0633\u062a\u0639\u0627\u062f\u0629\u060c \u0648\u0627\u062c\u0639\u0644 \u0643\u0644 \u062a\u0631\u062d\u064a\u0644 \u0645\u062d\u062f\u062f\u064b\u0627 \u0648\u0642\u0627\u0628\u0644\u064b\u0627 \u0644\u0644\u062a\u0643\u0631\u0627\u0631 \u0645\u062a\u0649 \u0623\u0645\u0643\u0646. \u0628\u0647\u0630\u0647 \u0627\u0644\u0637\u0631\u064a\u0642\u0629 \u062a\u0635\u0628\u062d \u062a\u063a\u064a\u064a\u0631\u0627\u062a \u0642\u0627\u0639\u062f\u0629 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u062e\u0637\u0648\u0629 \u0645\u0646\u0636\u0628\u0637\u0629 \u0628\u062f\u0644 \u062a\u0639\u062f\u064a\u0644 \u0645\u0628\u0627\u0634\u0631 \u063a\u064a\u0631 \u0642\u0627\u0628\u0644 \u0644\u0644\u062a\u0631\u0627\u062c\u0639.<\/p>","protected":false},"excerpt":{"rendered":"<p>\u062a\u062d\u062a\u0627\u062c \u062a\u0631\u062d\u064a\u0644 \u0642\u0627\u0639\u062f\u0629 SQLite \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Python \u0639\u0646\u062f\u0645\u0627 \u062a\u063a\u064a\u0651\u0631 \u0628\u0646\u064a\u0629 \u062c\u062f\u0648\u0644 \u0645\u0648\u062c\u0648\u062f \u0641\u064a \u062a\u0637\u0628\u064a\u0642 \u0641\u0639\u0644\u064a. \u0646\u062c\u0627\u062d \u0623\u0645\u0631 ALTER TABLE \u0648\u062d\u062f\u0647 \u0644\u0627 \u064a\u0636\u0645\u0646 \u0633\u0644\u0627\u0645\u0629 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a\u061b \u0644\u0630\u0644\u0643 \u0627\u062c\u0645\u0639 \u0628\u064a\u0646 \u0627\u0644\u0646\u0633\u062e\u0629 \u0627\u0644\u0627\u062d\u062a\u064a\u0627\u0637\u064a\u0629 \u0648\u0627\u0644\u0645\u0639\u0627\u0645\u0644\u0629 \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0644\u0646\u062a\u0627\u0626\u062c \u0648\u062e\u0637\u0629 \u0627\u0633\u062a\u0631\u062c\u0627\u0639 \u0645\u062c\u0631\u0628\u0629.<\/p>\n","protected":false},"author":2,"featured_media":847,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_keef_sources":[{"title":"SQLite ALTER TABLE","url":"https:\/\/sqlite.org\/lang_altertable.html","organization":"SQLite"},{"title":"SQLite Transactions","url":"https:\/\/www.sqlite.org\/lang_transaction.html","organization":"SQLite"},{"title":"Python sqlite3","url":"https:\/\/docs.python.org\/3\/library\/sqlite3.html","organization":"Python"}],"footnotes":""},"categories":[120],"tags":[58,130],"class_list":["post-919","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data","tag-python","tag-sqlite"],"_links":{"self":[{"href":"https:\/\/keefwiki.com\/code\/wp-json\/wp\/v2\/posts\/919","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/keefwiki.com\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/keefwiki.com\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/keefwiki.com\/code\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/keefwiki.com\/code\/wp-json\/wp\/v2\/comments?post=919"}],"version-history":[{"count":2,"href":"https:\/\/keefwiki.com\/code\/wp-json\/wp\/v2\/posts\/919\/revisions"}],"predecessor-version":[{"id":924,"href":"https:\/\/keefwiki.com\/code\/wp-json\/wp\/v2\/posts\/919\/revisions\/924"}],"wp:attachment":[{"href":"https:\/\/keefwiki.com\/code\/wp-json\/wp\/v2\/media?parent=919"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/keefwiki.com\/code\/wp-json\/wp\/v2\/categories?post=919"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/keefwiki.com\/code\/wp-json\/wp\/v2\/tags?post=919"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}