[{"data":1,"prerenderedAt":590},["ShallowReactive",2],{"content-/edinet-turso-db-setup":3,"all-pages-for-dir":588,"og-image-/edinet-turso-db-setup":589},{"id":4,"title":5,"body":6,"category":568,"description":569,"extension":570,"meta":571,"navigation":505,"path":572,"project_name":573,"published":574,"publishedAt":575,"seo":576,"stem":577,"tags":578,"todo":585,"updatedAt":586,"__hash__":587},"pages/2026-04/2026-04-09/edinet-turso-db-setup.md","EDINET APIで取得した財務データをTurso DBに格納するPythonスクリプトを構築した",{"type":7,"value":8,"toc":552},"minimark",[9,14,23,26,30,33,43,52,61,86,89,182,184,188,191,197,207,221,227,229,233,243,246,264,267,269,272,276,283,286,289,369,372,374,378,381,384,386,390,393,413,417,420,422,426,429,447,450,452,456,459,465,483,530,540,542,545,548],[10,11,13],"h1",{"id":12},"edinet-apiで取得した財務データをturso-dbに格納する","EDINET APIで取得した財務データをTurso DBに格納する",[15,16,17,18,22],"p",{},"EDINET APIで会計ソフトA（E33390）の財務データを引っ張ってきて、Turso DB（東京リージョン）に流し込むPythonスクリプト ",[19,20,21],"code",{},"store_to_turso.py"," を一から書いた。最終的にChart.jsで36チャートのダッシュボードHTMLを吐き出すところまで到達したが、道中の環境構築で何度もつまずいた。",[24,25],"hr",{},[27,28,29],"h2",{"id":29},"libsqlパッケージ選定の三転四転",[15,31,32],{},"Turso DBにPythonから接続するパッケージ選びで3回転んだ。",[15,34,35,42],{},[36,37,38,39],"strong",{},"1回目: ",[19,40,41],{},"libsql-experimental"," -- pip installが通らない。調べるとWindows向けのビルド済みwheelが存在しなかった。Rustのビルドツールチェーンが要求されるが、それを入れてまで使うパッケージではない。",[15,44,45,51],{},[36,46,47,48],{},"2回目: ",[19,49,50],{},"libsql-client"," -- インストールは通る。しかしHTTP経由の接続しかサポートしておらず、Embedded Replica（ローカルDBファイル + クラウド同期）が使えない。読み取りのたびにHTTPラウンドトリップが走るので、レスポンスがmsオーダーになる。",[15,53,54,60],{},[36,55,56,57],{},"3回目: ",[19,58,59],{},"libsql"," -- prebuilt wheelがWindows向けにも提供されていて、pip一発で入った。Embedded Replicaにも対応している。これで決着。",[62,63,68],"pre",{"className":64,"code":65,"language":66,"meta":67,"style":67},"language-bash shiki shiki-themes vitesse-light vitesse-light","pip install libsql\n","bash","",[19,69,70],{"__ignoreMap":67},[71,72,75,79,83],"span",{"class":73,"line":74},"line",1,[71,76,78],{"class":77},"senZ8","pip",[71,80,82],{"class":81},"sdGka"," install",[71,84,85],{"class":81}," libsql\n",[15,87,88],{},"接続コードは数行で済む:",[62,90,94],{"className":91,"code":92,"language":93,"meta":67,"style":67},"language-python shiki shiki-themes vitesse-light vitesse-light","import libsql_experimental as libsql\nconn = libsql.connect(\"local.db\", sync_url=TURSO_URL, auth_token=TOKEN)\nconn.sync()\n","python",[19,95,96,111,168],{"__ignoreMap":67},[71,97,98,102,106,109],{"class":73,"line":74},[71,99,101],{"class":100},"sHkkW","import",[71,103,105],{"class":104},"sG7-3"," libsql_experimental ",[71,107,108],{"class":100},"as",[71,110,85],{"class":104},[71,112,114,117,121,124,127,130,133,137,140,142,145,149,151,155,157,160,162,165],{"class":73,"line":113},2,[71,115,116],{"class":104},"conn ",[71,118,120],{"class":119},"shFtX","=",[71,122,123],{"class":104}," libsql",[71,125,126],{"class":119},".",[71,128,129],{"class":104},"connect",[71,131,132],{"class":119},"(",[71,134,136],{"class":135},"sMJiu","\"",[71,138,139],{"class":81},"local.db",[71,141,136],{"class":135},[71,143,144],{"class":119},",",[71,146,148],{"class":147},"s4oTP"," sync_url",[71,150,120],{"class":119},[71,152,154],{"class":153},"snbK4","TURSO_URL",[71,156,144],{"class":119},[71,158,159],{"class":147}," auth_token",[71,161,120],{"class":119},[71,163,164],{"class":153},"TOKEN",[71,166,167],{"class":119},")\n",[71,169,171,174,176,179],{"class":73,"line":170},3,[71,172,173],{"class":104},"conn",[71,175,126],{"class":119},[71,177,178],{"class":104},"sync",[71,180,181],{"class":119},"()\n",[24,183],{},[27,185,187],{"id":186},"turso-cliインストールの迷走","Turso CLIインストールの迷走",[15,189,190],{},"CLIの導入でもWindowsの壁にぶつかった。",[15,192,193,196],{},[36,194,195],{},"PowerShellインストールスクリプト"," -- 公式ドキュメント通りに実行したが、スクリプトが途中でエラーを吐いて止まった。",[15,198,199,202,203,206],{},[36,200,201],{},"ZIPダウンロード"," -- GitHubリリースからWindows用バイナリを直接落とした。展開して実行したら ",[19,204,205],{},"tursodb.exe"," という名前で、これはDB本体（libSQL）であってCLI管理ツールではなかった。DB作成やトークン管理のコマンドが一切ない。",[15,208,209,212,213,216,217,220],{},[36,210,211],{},"WSLで導入"," -- WSL上のLinuxでCLIをインストールしたら、すんなり動いた。",[19,214,215],{},"turso db create","、",[19,218,219],{},"turso db tokens create"," が通る。",[15,222,223,226],{},[36,224,225],{},"最終的な気づき"," -- Turso Webダッシュボード（app.turso.tech）でDB作成、トークン発行、テーブル確認、SQLクエリ実行まで全部できる。CLIを入れる必要がそもそもなかった。ダッシュボードのUIで東京リージョン（nrt）を選んでDBを作成し、認証トークンを発行した。",[24,228],{},[27,230,232],{"id":231},"embedded-replicaの動作検証","Embedded Replicaの動作検証",[15,234,235,236,238,239,242],{},"Embedded Replicaの挙動を手元で確認した。ローカルに ",[19,237,139],{}," ファイルが生成され、書き込みはまずローカルDBに入り、",[19,240,241],{},"conn.sync()"," でクラウドのTurso DBと同期される。",[15,244,245],{},"読み取り速度の差が歴然としていた:",[247,248,249,257],"ul",{},[250,251,252,253,256],"li",{},"ローカル読み取り: ",[36,254,255],{},"μsオーダー","（マイクロ秒）",[250,258,259,260,263],{},"HTTP経由読み取り: ",[36,261,262],{},"msオーダー","（ミリ秒）",[15,265,266],{},"ローカルにデータがキャッシュされるので、分析用途で同じデータを繰り返し読む場面ではHTTP経由と比べて桁違いに速い。",[24,268],{},[27,270,271],{"id":271},"データ取得と格納",[273,274,275],"h3",{"id":275},"companiesテーブルの追加",[15,277,278,279,282],{},"企業コード（E33390）から企業名を自動取得する仕組みを入れた。EDINETの検索API（認証不要・レート制限外）を叩くと、企業名が返ってくる。これを ",[19,280,281],{},"companies"," テーブルに格納して、以降のクエリで企業名をJOINできるようにした。",[273,284,285],{"id":285},"全6エンドポイントのデータ取得",[15,287,288],{},"EDINET APIの以下6エンドポイントからデータを引いて、それぞれ対応するテーブルに格納した:",[290,291,292,305],"table",{},[293,294,295],"thead",{},[296,297,298,302],"tr",{},[299,300,301],"th",{},"エンドポイント",[299,303,304],{},"内容",[306,307,308,319,329,339,349,359],"tbody",{},[296,309,310,316],{},[311,312,313],"td",{},[19,314,315],{},"financials",[311,317,318],{},"年次財務データ",[296,320,321,326],{},[311,322,323],{},[19,324,325],{},"financials_quarterly",[311,327,328],{},"四半期財務データ",[296,330,331,336],{},[311,332,333],{},[19,334,335],{},"segments",[311,337,338],{},"セグメント情報",[296,340,341,346],{},[311,342,343],{},[19,344,345],{},"employees",[311,347,348],{},"従業員データ",[296,350,351,356],{},[311,352,353],{},[19,354,355],{},"management",[311,357,358],{},"経営指標",[296,360,361,366],{},[311,362,363],{},[19,364,365],{},"credit_score",[311,367,368],{},"信用スコア",[15,370,371],{},"スクリプトは各エンドポイントを順に叩き、レスポンスJSONをパースしてINSERT OR REPLACEでTursoDB上のテーブルに流し込む構成にした。",[24,373],{},[27,375,377],{"id":376},"chartjsダッシュボード生成","Chart.jsダッシュボード生成",[15,379,380],{},"取得した全データをChart.jsで可視化するHTMLを生成した。6エンドポイント x 複数指標で合計36チャート。売上推移、利益率、セグメント別売上構成、従業員数推移、信用スコア変動などを一画面で俯瞰できる。",[15,382,383],{},"HTMLファイル1枚に全チャートを埋め込み、ブラウザで開くだけで閲覧できる構成にした。外部依存はChart.jsのCDNのみ。",[24,385],{},[27,387,389],{"id":388},"fy2022の販管費急増を読み解く","FY2022の販管費急増を読み解く",[15,391,392],{},"ダッシュボードを眺めていて、FY2022で販管費が跳ね上がっているのが目に飛び込んできた。中身を掘ると:",[247,394,395,401,407],{},[250,396,397,400],{},[36,398,399],{},"CM・広告費が約40億円",": テレビCMやWeb広告への大規模投下",[250,402,403,406],{},[36,404,405],{},"M&A関連",": 証券会社の買収に伴う費用",[250,408,409,412],{},[36,410,411],{},"採用競争の激化",": SaaS各社との人材獲得合戦で採用コストが膨張",[273,414,416],{"id":415},"無形資産のれん-ソフトウェアの積み上がり","無形資産（のれん + ソフトウェア）の積み上がり",[15,418,419],{},"BSを見ると無形資産が年々積み上がっている。これはM&Aで発生した「のれん」と、自社開発のソフトウェア（人件費の資産計上分）が二重に乗っている。SaaS企業特有のBS構造で、開発者の人件費がPLの費用ではなくBSの資産として計上されるため、見かけ上の利益が膨らむ点に注意が要る。",[24,421],{},[27,423,425],{"id":424},"tursoの無料枠とセキュリティ","Tursoの無料枠とセキュリティ",[15,427,428],{},"Tursoの無料プランの枠を確認した:",[247,430,431,437,442],{},[250,432,433,436],{},[36,434,435],{},"500データベース","まで作成可能",[250,438,439],{},[36,440,441],{},"9GBストレージ",[250,443,444],{},[36,445,446],{},"月間10億行の読み取り",[15,448,449],{},"個人の分析用途なら余裕がある。セキュリティモデルはトークンベース認証で、DB単位でトークンを発行・失効できる。ダッシュボードからワンクリックでトークンをローテーションできるのも確認した。",[24,451],{},[27,453,455],{"id":454},"apiキー更新のハマりどころ","APIキー更新のハマりどころ",[15,457,458],{},"最後にAPIキーの更新で30分ほど溶かした。",[15,460,461,464],{},[19,462,463],{},".env"," 内のEDINET APIキーが期限切れになっていたので新しいキーに書き換えた。ところがスクリプトを実行しても古いキーで認証エラーが出続ける。",[15,466,467,468,471,472,475,476,478,479,482],{},"原因は ",[19,469,470],{},"python-dotenv"," の ",[19,473,474],{},"load_dotenv()"," だった。",[19,477,474],{}," はデフォルトで ",[19,480,481],{},"override=False"," になっており、すでに環境変数に読み込まれている値を上書きしない。同一プロセス内で一度読み込まれた値がキャッシュされていた。",[62,484,486],{"className":91,"code":485,"language":93,"meta":67,"style":67},"# NG: 既存の環境変数を上書きしない\nload_dotenv()\n\n# OK: 明示的にoverrideする\nload_dotenv(override=True)\n",[19,487,488,494,501,507,513],{"__ignoreMap":67},[71,489,490],{"class":73,"line":74},[71,491,493],{"class":492},"sxvE3","# NG: 既存の環境変数を上書きしない\n",[71,495,496,499],{"class":73,"line":113},[71,497,498],{"class":104},"load_dotenv",[71,500,181],{"class":119},[71,502,503],{"class":73,"line":170},[71,504,506],{"emptyLinePlaceholder":505},true,"\n",[71,508,510],{"class":73,"line":509},4,[71,511,512],{"class":492},"# OK: 明示的にoverrideする\n",[71,514,516,518,520,523,525,528],{"class":73,"line":515},5,[71,517,498],{"class":104},[71,519,132],{"class":119},[71,521,522],{"class":147},"override",[71,524,120],{"class":119},[71,526,527],{"class":100},"True",[71,529,167],{"class":119},[15,531,532,533,536,537,539],{},"スクリプトの先頭で ",[19,534,535],{},"override=True"," を付けて解決した。",[19,538,474],{}," のデフォルト挙動を知らなかったのは盲点だった。",[24,541],{},[27,543,544],{"id":544},"まとめ",[15,546,547],{},"EDINET API → Turso DB → Chart.jsダッシュボードのパイプラインが一本通った。Windowsでのlibsqlパッケージ選定とTurso CLI導入で遠回りしたが、最終的にはpip一発 + Webダッシュボードというシンプルな構成に落ち着いた。Embedded Replicaのローカル読み取り速度（μs）は、分析ワークロードで繰り返しクエリを投げる用途に向いている。",[549,550,551],"style",{},"html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .sG7-3, html code.shiki .sG7-3{--shiki-default:#393A34;--shiki-dark:#393A34}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .snbK4, html code.shiki .snbK4{--shiki-default:#A65E2B;--shiki-dark:#A65E2B}html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}",{"title":67,"searchDepth":113,"depth":113,"links":553},[554,555,556,557,561,562,565,566,567],{"id":29,"depth":113,"text":29},{"id":186,"depth":113,"text":187},{"id":231,"depth":113,"text":232},{"id":271,"depth":113,"text":271,"children":558},[559,560],{"id":275,"depth":170,"text":275},{"id":285,"depth":170,"text":285},{"id":376,"depth":113,"text":377},{"id":388,"depth":113,"text":389,"children":563},[564],{"id":415,"depth":170,"text":416},{"id":424,"depth":113,"text":425},{"id":454,"depth":113,"text":455},{"id":544,"depth":113,"text":544},"dev","EDINET APIから会計ソフトAの財務データを取得し、Turso DB（東京リージョン）にPythonで格納するまでの構築記録。libsqlパッケージ選定、Turso CLI導入、Embedded Replicaの検証、Chart.jsダッシュボード生成まで","md",{},"/edinet-turso-db-setup","misc-dev",false,"2026-04-09T00:00:00.000Z",{"title":5,"description":569},"2026-04/2026-04-09/edinet-turso-db-setup",[579,580,59,581,582,583,584],"EDINET API","Turso","Python","財務データ","Embedded Replica","Chart.js","memo",null,"HM9KXuaJlwJlNcf71dVIN3nt8obzKdEIyThGAQXV7lM",[],"https://log.eurekapu.com/favicon.svg",1775770074078]