[Julia][Python]FastAPIを用いてJulia-Python連携を試してみた

## はじめに

　データ分析や機械学習などに利用できるプログラムとして、Juliaがあると知った。
　以下３点のメリットから今後利用することがあるかもしれないので、備忘録として初歩的なことから欲しかった資料をまとめていく。
　[1]Pythonと同じようにライブラリを利用できる
　[2]実行速度がC言語よりも速い
　[3]PythonやC言語と連携することもできる

## 実行環境
　参考資料[1]で構築したVSCにおけるWSL2で実行している。
　また、PostgreSQL環境構築は参考資料[2]で実施した内容となる。

## Package情報
　参考資料[3]を参考に以下コマンドで必要なパッケージをインストールできるが、バージョン違いによって動作不調を起こす可能性があるため、Package情報も記載する。

<details>
<summary>Mainfest.toml（クリックで展開）</summary>

~~~Mainfest.toml
# This file is machine-generated - editing it directly is not advised

julia_version = "1.11.4"
manifest_format = "2.0"
project_hash = "b9f0736169ee8408e455a414c5b8dfaf8d9fda2d"

[[deps.ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
version = "1.1.2"

[[deps.Artifacts]]
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
version = "1.11.0"

[[deps.Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
version = "1.11.0"

[[deps.CSV]]
deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "PrecompileTools", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings", "WorkerUtilities"]
git-tree-sha1 = "deddd8725e5e1cc49ee205a1964256043720a6c3"
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
version = "0.10.15"

[[deps.CodecZlib]]
deps = ["TranscodingStreams", "Zlib_jll"]
git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9"
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
version = "0.7.8"

[[deps.Compat]]
deps = ["TOML", "UUIDs"]
git-tree-sha1 = "8ae8d32e09f0dcf42a36b90d4e17f5dd2e4c4215"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "4.16.0"
weakdeps = ["Dates", "LinearAlgebra"]

    [deps.Compat.extensions]
    CompatLinearAlgebraExt = "LinearAlgebra"

[[deps.CompilerSupportLibraries_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
version = "1.1.1+0"

[[deps.CondaPkg]]
deps = ["JSON3", "Markdown", "MicroMamba", "Pidfile", "Pkg", "Preferences", "Scratch", "TOML", "pixi_jll"]
git-tree-sha1 = "6aedabfa737e647664ae87f933d3678dad5f61d7"
uuid = "992eb4ea-22a4-4c89-a5bb-47a3300528ab"
version = "0.2.28"

[[deps.Crayons]]
git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15"
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
version = "4.1.1"

[[deps.DataAPI]]
git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.16.0"

[[deps.DataFrames]]
deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"]
git-tree-sha1 = "fb61b4812c49343d7ef0b533ba982c46021938a6"
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
version = "1.7.0"

[[deps.DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.22"

[[deps.DataValueInterfaces]]
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
version = "1.0.0"

[[deps.Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
version = "1.11.0"

[[deps.Downloads]]
deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
version = "1.6.0"

[[deps.FilePathsBase]]
deps = ["Compat", "Dates"]
git-tree-sha1 = "3bab2c5aa25e7840a4b065805c0cdfc01f3068d2"
uuid = "48062228-2e41-5def-b9a4-89aafe57970f"
version = "0.9.24"
weakdeps = ["Mmap", "Test"]

    [deps.FilePathsBase.extensions]
    FilePathsBaseMmapExt = "Mmap"
    FilePathsBaseTestExt = "Test"

[[deps.FileWatching]]
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
version = "1.11.0"

[[deps.Future]]
deps = ["Random"]
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"
version = "1.11.0"

[[deps.InlineStrings]]
git-tree-sha1 = "6a9fde685a7ac1eb3495f8e812c5a7c3711c2d5e"
uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48"
version = "1.4.3"

    [deps.InlineStrings.extensions]
    ArrowTypesExt = "ArrowTypes"
    ParsersExt = "Parsers"

    [deps.InlineStrings.weakdeps]
    ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd"
    Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"

[[deps.InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
version = "1.11.0"

[[deps.InvertedIndices]]
git-tree-sha1 = "6da3c4316095de0f5ee2ebd875df8721e7e0bdbe"
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
version = "1.3.1"

[[deps.IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[deps.JLLWrappers]]
deps = ["Artifacts", "Preferences"]
git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.7.0"

[[deps.JSON3]]
deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"]
git-tree-sha1 = "196b41e5a854b387d99e5ede2de3fcb4d0422aae"
uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
version = "1.14.2"

    [deps.JSON3.extensions]
    JSON3ArrowExt = ["ArrowTypes"]

    [deps.JSON3.weakdeps]
    ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd"

[[deps.LaTeXStrings]]
git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.4.0"

[[deps.LazyArtifacts]]
deps = ["Artifacts", "Pkg"]
uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3"
version = "1.11.0"

[[deps.LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"
version = "0.6.4"

[[deps.LibCURL_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"
version = "8.6.0+0"

[[deps.LibGit2]]
deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
version = "1.11.0"

[[deps.LibGit2_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"]
uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5"
version = "1.7.2+0"

[[deps.LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
version = "1.11.0+1"

[[deps.Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
version = "1.11.0"

[[deps.LinearAlgebra]]
deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
version = "1.11.0"

[[deps.Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
version = "1.11.0"

[[deps.MacroTools]]
git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522"
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
version = "0.5.16"

[[deps.Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
version = "1.11.0"

[[deps.MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
version = "2.28.6+0"

[[deps.MicroMamba]]
deps = ["Pkg", "Scratch", "micromamba_jll"]
git-tree-sha1 = "011cab361eae7bcd7d278f0a7a00ff9c69000c51"
uuid = "0b3b1443-0f03-428d-bdfb-f27f9c1191ea"
version = "0.1.14"

[[deps.Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.2.0"

[[deps.Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"
version = "1.11.0"

[[deps.MozillaCACerts_jll]]
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
version = "2023.12.12"

[[deps.NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
version = "1.2.0"

[[deps.OpenBLAS_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
version = "0.3.27+1"

[[deps.OrderedCollections]]
git-tree-sha1 = "cc4054e898b852042d7b503313f7ad03de99c3dd"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.8.0"

[[deps.Parsers]]
deps = ["Dates", "PrecompileTools", "UUIDs"]
git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.8.3"

[[deps.Pidfile]]
deps = ["FileWatching", "Test"]
git-tree-sha1 = "2d8aaf8ee10df53d0dfb9b8ee44ae7c04ced2b03"
uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307"
version = "1.3.0"

[[deps.Pkg]]
deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
version = "1.11.0"

    [deps.Pkg.extensions]
    REPLExt = "REPL"

    [deps.Pkg.weakdeps]
    REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[deps.PooledArrays]]
deps = ["DataAPI", "Future"]
git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3"
uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
version = "1.4.3"

[[deps.PrecompileTools]]
deps = ["Preferences"]
git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f"
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
version = "1.2.1"

[[deps.Preferences]]
deps = ["TOML"]
git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.4.3"

[[deps.PrettyTables]]
deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"]
git-tree-sha1 = "1101cd475833706e4d0e7b122218257178f48f34"
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
version = "2.4.0"

[[deps.Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
version = "1.11.0"

[[deps.PythonCall]]
deps = ["CondaPkg", "Dates", "Libdl", "MacroTools", "Markdown", "Pkg", "Requires", "Serialization", "Tables", "UnsafePointers"]
git-tree-sha1 = "feab249add2d40873acbd6b286b450bd30b083dd"
uuid = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"
version = "0.9.24"

[[deps.Random]]
deps = ["SHA"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
version = "1.11.0"

[[deps.Reexport]]
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.2.2"

[[deps.Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.3.1"

[[deps.SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
version = "0.7.0"

[[deps.Scratch]]
deps = ["Dates"]
git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386"
uuid = "6c6a2e73-6563-6170-7368-637461726353"
version = "1.2.1"

[[deps.SentinelArrays]]
deps = ["Dates", "Random"]
git-tree-sha1 = "712fb0231ee6f9120e005ccd56297abbc053e7e0"
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
version = "1.4.8"

[[deps.Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
version = "1.11.0"

[[deps.SortingAlgorithms]]
deps = ["DataStructures"]
git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085"
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
version = "1.2.1"

[[deps.Statistics]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0"
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
version = "1.11.1"

    [deps.Statistics.extensions]
    SparseArraysExt = ["SparseArrays"]

    [deps.Statistics.weakdeps]
    SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[deps.StringManipulation]]
deps = ["PrecompileTools"]
git-tree-sha1 = "725421ae8e530ec29bcbdddbe91ff8053421d023"
uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e"
version = "0.4.1"

[[deps.StructTypes]]
deps = ["Dates", "UUIDs"]
git-tree-sha1 = "159331b30e94d7b11379037feeb9b690950cace8"
uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
version = "1.11.0"

[[deps.TOML]]
deps = ["Dates"]
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
version = "1.0.3"

[[deps.TableTraits]]
deps = ["IteratorInterfaceExtensions"]
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"

[[deps.Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"]
git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.12.0"

[[deps.Tar]]
deps = ["ArgTools", "SHA"]
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
version = "1.10.0"

[[deps.Test]]
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
version = "1.11.0"

[[deps.TranscodingStreams]]
git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742"
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
version = "0.11.3"

[[deps.UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
version = "1.11.0"

[[deps.Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
version = "1.11.0"

[[deps.UnsafePointers]]
git-tree-sha1 = "c81331b3b2e60a982be57c046ec91f599ede674a"
uuid = "e17b2a0c-0bdf-430a-bd0c-3a23cae4ff39"
version = "1.0.0"

[[deps.WeakRefStrings]]
deps = ["DataAPI", "InlineStrings", "Parsers"]
git-tree-sha1 = "b1be2855ed9ed8eac54e5caff2afcdb442d52c23"
uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5"
version = "1.4.2"

[[deps.WorkerUtilities]]
git-tree-sha1 = "cd1659ba0d57b71a464a29e64dbc67cfe83d54e7"
uuid = "76eceee3-57b5-4d4a-8e66-0e911cebbf60"
version = "1.6.1"

[[deps.Zlib_jll]]
deps = ["Libdl"]
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
version = "1.2.13+1"

[[deps.libblastrampoline_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"
version = "5.11.0+0"

[[deps.micromamba_jll]]
deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"]
git-tree-sha1 = "b4a5a3943078f9fd11ae0b5ab1bdbf7718617945"
uuid = "f8abcde7-e9b7-5caa-b8af-a437887ae8e4"
version = "1.5.8+0"

[[deps.nghttp2_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"
version = "1.59.0+0"

[[deps.p7zip_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
version = "17.4.0+2"

[[deps.pixi_jll]]
deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"]
git-tree-sha1 = "f349584316617063160a947a82638f7611a8ef0f"
uuid = "4d7b5844-a134-5dcd-ac86-c8f19cd51bed"
version = "0.41.3+0"

~~~

</details>

<details>
<summary>Project.toml（クリックで展開）</summary>

~~~Project.toml
[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"
~~~

</details>

　また、Python側のパッケージ情報は以下の通り。

<details>
<summary>requirements.txt（クリックで展開）</summary>

~~~requirements.txt
filelock==3.18.0
juliacall==0.9.24
juliapkg==0.1.16
semver==3.0.4
setuptools==75.8.0
wheel==0.45.1
fastapi==0.115.12
uvicorn==0.34.0
~~~

</details>

## プログラム構成
  以下の構成となっている。
  .apiは API（ルーティング）を定義する場所、.serviceは実際の処理（ロジック）を置く場所になっている。
main.pyは、アプリの起動ポイントとなっている。

```
.app
├─.api
|  └─call_julia.py
├─.file
|  └─test.csv
├─.service
|  └─.core
|    └─do_sql.jl
|    └─load_file.jl
|  └─.interface
|    └─__init__.py
|    └─call_julia_service.py
|  └─__init__.py
├─.sql
|  └─test.sql
├─__init__.py
├─main.py
├─Mainfest.toml
├─Project.toml
└─requirements.txt
```

## プログラム
<details>
<summary>main.py（クリックで展開）</summary>

~~~main.py
from fastapi import FastAPI
from app.api import call_julia 

app = FastAPI()

# ルーターをFastAPI本体に登録

app.include_router(call_julia.router)
app.include_router(call_julia.router2)
~~~

</details>

<details>
<summary>call_julia.py（クリックで展開）</summary>

~~~call_julia.py
from fastapi import APIRouter, Form
from typing import List
from app.services.interface.call_julia_service import call_read_csv_to_dataframe
from app.services.interface.call_julia_service import call_select_sql

# ファイルを取り込むためのルーター
router = APIRouter(tags=["ファイル取り込み"])

# SQL実行するためのルーター
router2 = APIRouter(tags=["SQL実行"])

# 読み込んだCSVファイルをデータフレームに格納して、返却する
@router.post(
    "/load/{var_name}",
    summary = "CSVファイルを読み込んで、データフレームに登録する",
    description = "CSVファイルを読み込んで、任意の名前のデータフレームに登録する。"
)
async def load_csv_files(
    file_name: str = Form(
        ..., 
        description=(
            "読み込ませるCSV名を記載\n"
            "例：test.csv"
        ), 
    ),

    header_number: int = Form(        
        description=(
            "ヘッダーにする行数を記載。なければ空白\n"
            "例：1"
        ), 
    ),
    ):

    result = await call_read_csv_to_dataframe(file_name, header_number)

    return result

# SELECT文を実行して返却する
@router2.post(
    "/sql/select/{var_name}",
    summary = "SQLファイルを読み込んで、データフレームに格納する",
    description = "Julia側でSQLファイルを読み込んで、SELECT実行する"
)
async def sql_select(
    file_name: str = Form(
        ..., 
        description=(
            "読み込ませるSQL名を記載。SELECT文を指定する\n"
            "例：test.sql"
        ), 
    )
):
    result = await call_select_sql(file_name)

    return result
~~~

</details>

 参考資料[5]ではPythonコード上にパッケージ利用文を明記しなくても問題なくPythonからJuliaを呼び出すことができたが、今回の構成のようにtomlファイルとJuliaファイルが別々に格納されている場合、どのパッケージを利用するか明記しないとJuliaファイルを実行できなかったので、追記している。
　また、return文をsuccess文表示にしているが、Julia側の変数の型とPython側の変数の型が不一致でうまく受け渡しができなかったので、単純にsuccess表示としている。

``` call_julia_service.py
from fastapi import UploadFile
from juliacall import Main as jl
import os

# Juliaに渡すための .jl ファイルの絶対パスを取得
jl_file = os.path.abspath("/○○/app/services/core/load_file.jl").replace("\\", "/") #←相対パスだとうまくできなかったので、絶対パスで設定
jl_file = os.path.abspath("/○○/app/services/core/do_sql.jl").replace("\\", "/") #←相対パスだとうまくできなかったので、絶対パスで設定
project_root = "/○○/app" #←相対パスだとうまくできなかったので、絶対パスで設定

# Julia 環境を明示的に有効化
jl.seval('using Pkg')
jl.seval(f'Pkg.activate("{project_root}")') 

# Juliaで include
jl.seval(f'include("{jl_file}")')

#csvを読み込んで、Julia側でデータフレームにする
async def call_read_csv_to_dataframe(file_name, header_number):

    file_path =  os.path.join("/○○/app/file", file_name) #←相対パスだとうまくできなかったので、絶対パスで設定

    jl.read_csv_to_dataframe(file_path, header_number)

    return "success!"

#SQLファイルを読み込んで、SELECT実行する
async def call_select_sql(file_name):

    file_path =  os.path.join("/○○/app/sql", file_name) #←相対パスだとうまくできなかったので、絶対パスで設定

    jl.select_sql(file_path)

    return "success!"
```

``` load_file.jl
using CSV,DataFrames

# CSVを読み取り、データフレームに取り込む
function read_csv_to_dataframe(file_path::String, header_number::Union{Int, Nothing}=nothing)

    if header_number === nothing
        df = CSV.File(file_path; header=false) |> DataFrame
    
    else
        df = CSV.File(file_path; header=header_number) |> DataFrame
    
    end

    #Python側のデータフレーム型と、Julia側のデータフレーム型は一致しないので、コンソール上に結果確認用として表示させる
    println("データフレーム：")
    println(df)
    flush(stdout)

    #Python側に値を戻さないが、他のJuliaファイルからの呼び出しに備えて記載
    return df

end
```

```do_sql.jl
using LibPQ, DataFrames

conn = LibPQ.Connection("""
    host=localhost
    port=設定したホストポート番号
    dbname=設定したDB名
    user=設定したユーザ
    password=設定したパスワード
""")

function select_sql(filepath::String)
    #sqlファイルを読み込み
    sql = read(filepath, String)

    #SQLを実行
    sql_result = execute(conn, sql) 

    # DataFrameに変換（SELECT結果を取得）
    df_result = DataFrame(sql_result)

    #SELECT結果をそのまま表示できないので、データフレームに変換してコンソール上に結果確認用として表示させる
    println("SELECT結果：")
    println(df_result)
    flush(stdout)

    #Python側に値を戻さないが、他のJuliaファイルからの呼び出しに備えて記載
    return sql_result
end
```

## FastAPI画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1391358/d599a4b7-6626-43f4-8c57-69c8437681f9.png)

## 所感
　今回は外部アプリと連携することを念頭に、外部とのやり取りをFastAPI(Python),メイン処理部分をjulia,データ共有をPostgreSQLで構築してみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1391358/803da13f-dc7d-4ac6-942d-5089cabd3a4d.png)

　実装にあたり、同じデータフレームでもJuliaとPythonで型不一致など課題があり、データ型の統一に苦労した。そのため、Juliaの型がPythonのどの型に適合するか、正確に理解することが２つを組み合わせる際の重要なポイントとなってきそうだ。ただし参考資料[7]で数万より多くのデータがないとJuliaにメイン処理部分をやらせる意義が限定的と判明しているので、Python⇔Juliaの直接的な型変換というりよも、実運用する際は**Python⇔DB⇔Julia**を意識していくことになりそうだ。
　またファイル取り込みなどわざわざJuliaでやらなくても、Python側に閉じた処理で構築したほうがいい機能も発生するはずなので、Juliaでやれることは何か、どちらのほうが効率的に処理できるか、事前に必要機能を洗い出し、割り振りを定めておくことが大切となりそうだ。

## 参考資料
[1]svoboda, 『[Julia]VSCにおけるWSL2でのJulia　環境構築～サンプルコード実行まで』, https://qiita.com/svoboda/items/6a0ad624bc58a354edb3
[2]svoboda, 『[PostgreSQL][Python]VSCにおけるWSL2でのPostgreSQL環境構築』, https://qiita.com/svoboda/items/0d4234aea9c9082705b6
[3]svoboda, 『[Julia]仮想環境（Package）構築』, https://qiita.com/svoboda/items/ad77b77913eb78ac0b41
[4]svoboda, 『[Python]FastAPIの基本構造とひな形』, https://qiita.com/svoboda/items/c70f795547cd1726aa04
[5]svoboda, 『[Julia][Python]PythonからJuliaの呼び出し』, https://qiita.com/svoboda/items/fd5fe37da92d46cc6f67
[6]svoboda, 『[Julia]Postgresql接続確認』, https://qiita.com/svoboda/items/8524990ab5c7768bc9f9
[7]svoboda, 『[Julia]Pythonと速度比較』, https://qiita.com/svoboda/items/cf06a10628141d11389a