{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6f09f3c1",
   "metadata": {},
   "source": [
    "# 22-28 · Перенос данных через JSON\n",
    "\n",
    "Практика к разделу [«Перенос данных между базами»](../../site/chapters/glava-22/22-28-perenos-dannyh.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f936631",
   "metadata": {},
   "source": [
    "## Цель\n",
    "\n",
    "Перенести три строки из одной базы SQLite в другую через JSON как промежуточный формат — и проверить, что количество и содержимое совпали."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00ca812a",
   "metadata": {},
   "source": [
    "## Рабочий пример — исходная база"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "251cac9c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import sqlite3\n",
    "\n",
    "istochnik = sqlite3.connect(\":memory:\")\n",
    "istochnik.row_factory = sqlite3.Row\n",
    "istochnik.execute(\"CREATE TABLE tasks (id INTEGER PRIMARY KEY, title TEXT NOT NULL, done INTEGER NOT NULL DEFAULT 0)\")\n",
    "istochnik.executemany(\n",
    "    \"INSERT INTO tasks (title, done) VALUES (?, ?)\",\n",
    "    [(\"Купить хлеб\", 0), (\"Выучить SQL\", 1), (\"Собрать сайт\", 0)],\n",
    ")\n",
    "istochnik.commit()\n",
    "\n",
    "stroki = istochnik.execute(\"SELECT title, done FROM tasks ORDER BY id\").fetchall()\n",
    "dannye = [dict(stroka) for stroka in stroki]\n",
    "tekst_json = json.dumps(dannye, ensure_ascii=False)\n",
    "print(tekst_json)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2dd0dc7",
   "metadata": {},
   "source": [
    "## Эксперимент — импорт в новую базу"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e49393e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "zagruzhennye = json.loads(tekst_json)\n",
    "\n",
    "cel = sqlite3.connect(\":memory:\")\n",
    "cel.execute(\"CREATE TABLE tasks (id INTEGER PRIMARY KEY, title TEXT NOT NULL, done INTEGER NOT NULL DEFAULT 0)\")\n",
    "for zapis in zagruzhennye:\n",
    "    cel.execute(\"INSERT INTO tasks (title, done) VALUES (?, ?)\", (zapis[\"title\"], zapis[\"done\"]))\n",
    "cel.commit()\n",
    "\n",
    "itog = cel.execute(\"SELECT title, done FROM tasks ORDER BY id\").fetchall()\n",
    "print(itog)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00e34304",
   "metadata": {},
   "source": [
    "## Проверка результата"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3d1eb46b",
   "metadata": {},
   "outputs": [],
   "source": [
    "iskhodnye_nazvaniya = [s[\"title\"] for s in stroki]\n",
    "itogovye_nazvaniya = [s[0] for s in itog]\n",
    "\n",
    "assert len(itog) == len(stroki) == 3\n",
    "assert itogovye_nazvaniya == iskhodnye_nazvaniya\n",
    "assert [s[1] for s in itog] == [s[\"done\"] for s in stroki]\n",
    "print(\"Верно: количество строк и их содержимое совпадают после переноса через JSON.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3325ad1d",
   "metadata": {},
   "source": [
    "## Важная деталь\n",
    "\n",
    "Новые идентификаторы `id` в целевой базе назначаются заново — при вставке они не передавались явно. Это осознанный выбор для такого простого случая: если бы исходные `id` были важны (например, на них кто-то уже ссылается), их нужно было бы переносить явно и после этого проверить, что они остались уникальными."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Cartesian Python 3.14",
   "language": "python",
   "name": "cartesian-python314"
  },
  "language_info": {
   "name": "python",
   "version": "3.14.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
