スクリプトのお勉強

Doltを起動して、PythonからMySQL的アクセスしてみる

投稿日:

はじめに

お仕事で、運用データをどのようにプログラム的に保持するかは意外に難しいです。

この意味の運用データとは、例えば、接続先ホストとか、パスワードとか、運用の人が日常に使うデータを指します。

システムが使用するデータならMySQLのようなDBMSに入れればいいだけですが、
運用の人が使うデータをそれにしてしまうと頻繁に変えたり、そもそもどこにあるのか分からなくなったりします。

あと、よくある要件は、「履歴保管してくれ」です。

履歴というとカッコよく聞こえますが、要は設定変更で、よく間違えるからすぐに戻せないといけません。
DBMSだと、戻すのは面倒です。

長年探していたのですが、ふとDoltのことを見つけ、これがどのようなシステムなのかまずは調査してみようと思います。

どんな感じのプログラムなのか?

まずはどんなプログラムなのか理解するために、以下を行います。

  • 初期設定
  • テーブル生成/データ追加(MySQLクライアントから手動)
  • Python3からデータ追加/データコミット/タグ打ち
  • タグを打ったところまでデータを戻す(コマンドライン)

までしてみたいと思います。

動作環境

WSL2上で設定/確認しています。

  • WSL2
    • ubuntu 24.04
  • Dolt v1.86.1
  • MySQL クライアント 8.0.45
  • Python3 3.12.3
    • mysql-connector-python: 9.6.0

インストール

Doltは以下でインストールします。

$ sudo bash -c 'curl -L https://github.com/dolthub/dolt/releases/latest/download/install.sh | bash'

起動準備

なにも設定しないで起動すると、以下といわれます。

 $ dolt config --global --add user.email YOU@DOMAIN.COM
 $ dolt config --global --add user.name "YOUR NAME"

以下のように設定します。

$ dolt config --global --add user.email ke.tanino@gmail.com
Config successfully updated.
$ dolt config --global --add user.name "Kenichi Tanino"
Config successfully updated.

dolt initの時に設定してもしてもいいようです。

なお、設定すると以下のように設定ファイルが作成されます。

$ cat ~/.dolt/config_global.json
 {"user.email":"ke.tanino@gmail.com","user.name":"Kenichi Tanino"}

初期起動(MySQLとして起動)

以下のようにカレントディレクトリにしかつくられないようです。

私の感覚だとディレクトリを指定したいところですが、起動時にカレントディレクトリを指定すればいいので、これはこういうものと思っておきます。

以下のように起動して初期起動しておきます。

$ mkdir -p ~/dolt
$ cd ~/dolt
$ dolt init --name="root" --email="test@test"
Successfully initialized dolt data repository.

次に、以下のようにMySQL Serverとして起動しておきます。

$ dolt sql-server
Starting server with Config HP="localhost:3306"|T="28800000"|R="false"|L="info"|S="/tmp/mysql.sock"
INFO[0000] Creating root@localhost superuser
INFO[0000] Server ready. Accepting connections.
WARN[0000] secure_file_priv is set to "", which is insecure.
WARN[0000] Any user with GRANT FILE privileges will be able to read any file which the sql-server process can read.
WARN[0000] Please consider restarting the server with secure_file_priv set to a safe (or non-existent) directory.

テーブル生成/データ追加

テーブルは以下を作成します。

CREATE DATABASE processes;
CREATE TABLE tasks (
    id INT NOT NULL,
    title VARCHAR(255) NOT NULL,
    assignee VARCHAR(100),
    status VARCHAR(50) DEFAULT 'Todo', -- 'Todo', 'In Progress', 'Done'
    progress INT DEFAULT 0,
    due_date DATE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 作成日時
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新日時
    PRIMARY KEY (id)
);

CREATE TABLE task_logs (
    id INT NOT NULL AUTO_INCREMENT,
    task_id INT NOT NULL,
    comment TEXT,
    work_hours DECIMAL(4,1), -- 1.5時間など
    logged_by VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (task_id) REFERENCES tasks(id)
);

MySQLクライアントを使用して、テーブル作成します。

$ mysql --host 127.0.0.1 --port 3306 -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 8.0.33 Dolt

Copyright (c) 2000, 2026, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CREATE DATABASE processes;
Query OK, 1 row affected (0.03 sec)

mysql> use processes;
Database changed
mysql> CREATE TABLE tasks (
    ->     id INT NOT NULL,
    ->     title VARCHAR(255) NOT NULL,
    ->     assignee VARCHAR(100),
    -> status VARCHAR(50) DEFAULT 'Todo    status VARCHAR(50) DEFAULT 'Todo', -- 'Todo', 'In Progress', 'Done'
    ->     progress INT DEFAULT 0,
    ->     due_date DATE,
    ->     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 作成日時
    ->     updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新日時
    ->     PRIMARY KEY (id)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE task_logs (
    ->     id INT NOT NULL AUTO_INCREMENT,
    ->     task_id INT NOT NULL,
    ->     comment TEXT,
    ->     work_hours DECIMAL(4,1), -- 1.5時間など
),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (task_id) REFERENCES tasks(id)
);    ->     logged_by VARCHAR(100),
    ->     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    ->     PRIMARY KEY (id),
    ->     FOREIGN KEY (task_id) REFERENCES tasks(id)
    -> );
Query OK, 0 rows affected (0.00 sec)

create tableした際のDoltデータの持ち方(ファイル構造)

もちろんプログラムが変わると変わると思いますが、現状だと以下のようなファイル構造らしいです。

dotディレクトリ以下なので、もしこのディレクトリ自体をどこかに保存する場合はそのつもりで保存する必要があります。

$ ls -lRa
.:
total 24
drwxr-xr-x  5 tanino tanino 4096 Apr 11 13:44 .
drwxr-xr-x 72 tanino tanino 4096 Apr 11 13:44 ..
drwxr-xr-x  5 tanino tanino 4096 Apr 11 12:53 .dolt
drwxr-xr-x  2 tanino tanino 4096 Apr 11 11:24 .doltcfg
-rwxrwxrwx  1 tanino tanino 2154 Apr 11 11:24 config.yaml
drwxr-xr-x  3 tanino tanino 4096 Apr 11 11:28 processes

./.dolt:
total 32
drwxr-xr-x 5 tanino tanino 4096 Apr 11 12:53 .
drwxr-xr-x 5 tanino tanino 4096 Apr 11 13:44 ..
-rwxrwxrwx 1 tanino tanino  115 Apr 11 11:24 config.json
drwxr-xr-x 3 tanino tanino 4096 Apr 11 11:24 noms
-rwxrwxrwx 1 tanino tanino   83 Apr 11 10:47 repo_state.json
-rw------- 1 tanino tanino   46 Apr 11 11:24 sql-server.info
drwxr-xr-x 3 tanino tanino 4096 Apr 11 12:53 stats
drwxr-xr-x 2 tanino tanino 4096 Apr 11 10:47 temptf

Python3のサンプルプログラム

ここにサンプルコードを置いておきました。

起動方法は以下です。

$ python3 -m venv ./venv
$ source ./venv/bin/activate
$ pip install -r requirements.txt 
Collecting mysql-connector-python (from -r requirements.txt (line 1))
  Downloading mysql_connector_python-9.6.0-cp312-cp312-manylinux_2_28_x86_64.whl.metadata (11 kB)
Downloading mysql_connector_python-9.6.0-cp312-cp312-manylinux_2_28_x86_64.whl (34.5 MB)
$ python3 app.py
--- 1. ランダムデータの生成と挿入 ---
Task: バグ修正 (#187), Assignee: Dave, Status: Done, Progress: 5%
✔ データを挿入/更新しました。

--- 2. Dolt Commit ---
✔ コミット成功: 022ahp0 - Update task 187: Done (5%)

--- 3. Dolt Tag ---
✔ タグ 'REL_20260411130201' を作成しました。

--- 4. 履歴の確認 (最新3件) ---
[022ahp0] Update task 187: Done (5%)
[acn8rl2] Update task 698: In Progress (94%)
[tblt326] Update task 195: Done (82%)

起動後は以下のようなデータを格納します。

$ mysql -h 127.0.0.1 -uroot
mysql> select * from tasks;
+-----+---------------------------------+----------+-------------+----------+------------+---------------------+---------------------+| id  | title                           | assignee | status      | progress | due_date   | created_at          | updated_at          |
+-----+---------------------------------+----------+-------------+----------+------------+---------------------+---------------------+| 187 | バグ修正 (#187)                 | Dave     | Done        |        5 | 2026-04-21 | 2026-04-11 13:02:01 | 2026-04-11 13:02:01 |
| 195 | バグ修正 (#195)                 | Eve      | Done        |       82 | 2026-04-12 | 2026-04-11 12:57:03 | 2026-04-11 12:57:03 || 511 | ドキュメント更新 (#511)         | Dave     | Todo        |       58 | 2026-04-22 | 2026-04-11 12:55:10 | 2026-04-11 12:55:10 |
| 614 | テストコード作成 (#614)         | Bob      | In Progress |       57 | 2026-04-12 | 2026-04-11 12:53:47 | 2026-04-11 12:53:47 || 698 | ミーティング記録 (#698)         | Alice    | In Progress |       94 | 2026-04-16 | 2026-04-11 12:57:34 | 2026-04-11 12:57:34 |
+-----+---------------------------------+----------+-------------+----------+------------+---------------------+---------------------+
5 rows in set (0.01 sec)

mysql> select * from task_logs;
+----+---------+-----------------------------------+------------+-----------+---------------------+
| id | task_id | comment                           | work_hours | logged_by | created_at          |
+----+---------+-----------------------------------+------------+-----------+---------------------+
|  1 |     614 | 順調です                          |        1.4 | Bob       | 2026-04-11 12:53:47 |
|  2 |     511 | 明日までに終わらせます            |        2.9 | Dave      | 2026-04-11 12:55:10 |
|  3 |     195 | 順調です                          |        1.1 | Eve       | 2026-04-11 12:57:03 |
|  4 |     698 | 課題が発生中                      |        3.0 | Alice     | 2026-04-11 12:57:34 |
|  5 |     187 | 課題が発生中                      |        5.2 | Dave      | 2026-04-11 13:02:01 |
+----+---------+-----------------------------------+------------+-----------+---------------------+
5 rows in set (0.00 sec)

コマンドラインとMySQLについて

まず、Doltの基本として

DBMS内のdatabaseはディレクトリである

というのがあるようです。

データディレクトリが仮に~/doltだったとすると、processesというデータベースの内容をコマンドラインで見るには
以下のようにprocessesというディレクトリに移動する必要があります。

$ cd ~/dolt/processes
$ dolt log
~/dolt/processes$ dolt log
commit 7cjehb6tlkjjtiobilptkij6nbm0pgof (HEAD -> main, tag: REL_20260412125256)
Author: root <root@localhost>
Date:  Sun Apr 12 12:52:57 +0900 2026

        Update task 257: In Progress (80%)

commit 022ahp0tntpranm5qctt3eg7ngj5tf49 (tag: REL_20260411130201)
Author: root <root@localhost>
Date:  Sat Apr 11 13:02:01 +0900 2026

        Update task 187: Done (5%)

commit acn8rl2sdaudcmgsth2msn8imcd2urgi (tag: run-698-125734)
Author: root <root@localhost>
Date:  Sat Apr 11 12:57:34 +0900 2026

        Update task 698: In Progress (94%)

commit tblt32691l3k2i0hgbbcbohtclslc49j (tag: run-195-125703)
Author: root <root@localhost>
Date:  Sat Apr 11 12:57:03 +0900 2026

        Update task 195: Done (82%)

commit vrgfphdbc2ckdjsp6pgrpu7f62p6e55s
Author: root <root@localhost>
Date:  Sat Apr 11 12:55:10 +0900 2026

        Update task 511: Todo (58%)

commit dpjvpprpovp4ihdkn7gogoas3qu37g8v
Author: root <test@test>
Date:  Sat Apr 11 11:28:01 +0900 2026

        Initialize data repository

MySQLクライアントからは以下のようになります。

mysql> use processes;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT * FROM dolt_log;
+----------------------------------+-----------+----------------+-------------------------+------------------------------------+--------------+
| commit_hash                      | committer | email          | date                    | message                            | commit_order |
+----------------------------------+-----------+----------------+-------------------------+------------------------------------+--------------+
| 7cjehb6tlkjjtiobilptkij6nbm0pgof | root      | root@localhost | 2026-04-12 03:52:56.892 | Update task 257: In Progress (80%) |            6 |
| 022ahp0tntpranm5qctt3eg7ngj5tf49 | root      | root@localhost | 2026-04-11 04:02:01.425 | Update task 187: Done (5%)         |            5 |
| acn8rl2sdaudcmgsth2msn8imcd2urgi | root      | root@localhost | 2026-04-11 03:57:34.322 | Update task 698: In Progress (94%) |            4 |
| tblt32691l3k2i0hgbbcbohtclslc49j | root      | root@localhost | 2026-04-11 03:57:03.300 | Update task 195: Done (82%)        |            3 |
| vrgfphdbc2ckdjsp6pgrpu7f62p6e55s | root      | root@localhost | 2026-04-11 03:55:10.225 | Update task 511: Todo (58%)        |            2 |
| dpjvpprpovp4ihdkn7gogoas3qu37g8v | root      | test@test      | 2026-04-11 02:28:00.597 | Initialize data repository         |            1 |
+----------------------------------+-----------+----------------+-------------------------+------------------------------------+--------------+
6 rows in set (0.00 sec)

タグを指定してデータをロールバックする

まず現状のデータを表示させます。
タグで言うと REL_20260412125256 になります。

tanino@tanino-home-main:~/dolt/processes$ dolt sql -q "select * from tasks;"
+-----+-------------------------+----------+-------------+----------+------------+---------------------+---------------------+
| id  | title                   | assignee | status      | progress | due_date   | created_at          | updated_at          |
+-----+-------------------------+----------+-------------+----------+------------+---------------------+---------------------+
| 187 | バグ修正 (#187)         | Dave     | Done        | 5        | 2026-04-21 | 2026-04-11 13:02:01 | 2026-04-11 13:02:01 |
| 195 | バグ修正 (#195)         | Eve      | Done        | 82       | 2026-04-12 | 2026-04-11 12:57:03 | 2026-04-11 12:57:03 |
| 257 | テストコード作成 (#257) | Bob      | In Progress | 80       | 2026-04-15 | 2026-04-12 12:52:57 | 2026-04-12 12:52:57 |
| 511 | ドキュメント更新 (#511) | Dave     | Todo        | 58       | 2026-04-22 | 2026-04-11 12:55:10 | 2026-04-11 12:55:10 |
| 614 | テストコード作成 (#614) | Bob      | In Progress | 57       | 2026-04-12 | 2026-04-11 12:53:47 | 2026-04-11 12:53:47 |
| 698 | ミーティング記録 (#698) | Alice    | In Progress | 94       | 2026-04-16 | 2026-04-11 12:57:34 | 2026-04-11 12:57:34 |
+-----+-------------------------+----------+-------------+----------+------------+---------------------+---------------------+

タグ間(REL20260411130201…REL20260412125256)の差分は以下の通り

~/dolt/processes$ dolt diff REL_20260411130201...REL_20260412125256
diff --dolt a/task_logs b/task_logs
--- a/task_logs
+++ b/task_logs
 CREATE TABLE `task_logs` (
   `id` int NOT NULL AUTO_INCREMENT,
   `task_id` int NOT NULL,
   `comment` text,
   `work_hours` decimal(4,1),
   `logged_by` varchar(100),
   `created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`),
   KEY `task_id` (`task_id`),
   CONSTRAINT `task_logs_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;
+) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin;
+---+----+---------+------------------------+------------+-----------+---------------------+
|   | id | task_id | comment                | work_hours | logged_by | created_at          |
+---+----+---------+------------------------+------------+-----------+---------------------+
| + | 6  | 257     | 明日までに終わらせます | 3.3        | Bob       | 2026-04-12 12:52:57 |
+---+----+---------+------------------------+------------+-----------+---------------------+
diff --dolt a/tasks b/tasks
--- a/tasks
+++ b/tasks
+---+-----+-------------------------+----------+-------------+----------+------------+---------------------+---------------------+
|   | id  | title                   | assignee | status      | progress | due_date   | created_at          | updated_at          |
+---+-----+-------------------------+----------+-------------+----------+------------+---------------------+---------------------+
| + | 257 | テストコード作成 (#257) | Bob      | In Progress | 80       | 2026-04-15 | 2026-04-12 12:52:57 | 2026-04-12 12:52:57 |
+---+-----+-------------------------+----------+-------------+----------+------------+---------------------+---------------------+

タグ指定でデータを戻す

dolt resetでタグを指定して、データを戻します。

$:~/dolt/processes$ dolt reset --hard REL_20260411130201
### 257がない
$:~/dolt/processes$ dolt sql -q "select * from tasks;"
+-----+-------------------------+----------+-------------+----------+------------+---------------------+---------------------+
| id  | title                   | assignee | status      | progress | due_date   | created_at          | updated_at          |
+-----+-------------------------+----------+-------------+----------+------------+---------------------+---------------------+
| 187 | バグ修正 (#187)         | Dave     | Done        | 5        | 2026-04-21 | 2026-04-11 13:02:01 | 2026-04-11 13:02:01 |
| 195 | バグ修正 (#195)         | Eve      | Done        | 82       | 2026-04-12 | 2026-04-11 12:57:03 | 2026-04-11 12:57:03 |
| 511 | ドキュメント更新 (#511) | Dave     | Todo        | 58       | 2026-04-22 | 2026-04-11 12:55:10 | 2026-04-11 12:55:10 |
| 614 | テストコード作成 (#614) | Bob      | In Progress | 57       | 2026-04-12 | 2026-04-11 12:53:47 | 2026-04-11 12:53:47 |
| 698 | ミーティング記録 (#698) | Alice    | In Progress | 94       | 2026-04-16 | 2026-04-11 12:57:34 | 2026-04-11 12:57:34 |
+-----+-------------------------+----------+-------------+----------+------------+---------------------+---------------------+

上記のように戻すことができてるので、使えるかも、というところです。

終わりに

思ったよりは使えるようです。まずはテストで使ってみたりしようと思います。

参考

  • https://docs.dolthub.com/guides/cheat-sheet
    Doltのコマンドを忘れたらこれ。

-スクリプトのお勉強
-, ,

執筆者:

関連記事

pysnmp v6 から v7 への移行

はじめに 前回の記事でPythonによるSNMPTrapの送信について記事を書きました。 その後、PythonからのSNMPTrap送信する方法を調査したら、方法が変わっていることに気づきしました。 …

Reflex(Python) をSQLite + ログイン機能付きで使ってみる

2024年現在のWebアプリ作成方法の一つとして、「PythonだけでWebアプリを完結する」作り方があります。 その一つとしてReflexというのがあります。 Reflexとは PythonのWeb …

Selenium + Python によるアップロードアプリの動作確認プログラム作成

私の周りでは、なぜかSeleniumが流行っている模様です。 私自身は、Webアプリ的なのも作ってますが、あまり使ってなかったので、使ってみようと思います。 前回作成した、Djangoのupload_ …

Python(prophet)で体重予測

最近ダイエットしていて、少しだけ成果が出たので、グラフ表示しようと思ってました。そのついでにこれからの予測もしてみようということで、過去のデータを集め、グラフ表示してみます。 google Colab …

Pythonパッケージ管理の歴史

歴史っても、あまり過去に興味がないので、、 Pythonのパッケージ管理の歴史は、常に流動的で、そもそもからして、とてもじゃないがまとめて説明できるようなものではないです。 はっきり言って昔からよく分 …

    google オプトアウト Click here to opt-out.