はじめに
PostgreSQL
の環境をローカルではDocker
を使っていたが、Supabase
のDBを使ってみたいなと思ったので使ってみる。
環境
Windows 11 Professional
Visual Studio 2022 Community
準備
- Supabase
https://supabase.com/
でアカウントを作成していること。
プロジェクトを作成する
手順
接続文字列の取得
サイドバーの「Project Settings」を選択する
「Database」を選択する
Connection Parametersを確認して接続文字列を作成する
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
- "PostgreSqlConnection": "Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=postgres",
+ "PostgreSqlConnection": "Host=[Host];Port=6543;Username=[UserName];Password=[Password]"
}
}
DBのマイグレートを実行する
※今回使用しているプロジェクトはDBのマイグレートをできるようにしているので、以下でマイグレートをする。
- メニューバーの「ツール」 > 「NuGet パッケージ マネージャー」 > 「パッケージ マネージャー コンソール」を選択
- NuGetコンソールで以下を実行する。
Update-Database
エラーになる↓
ログ
PM> Update-Database
Build started...
Build succeeded.
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (28ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT EXISTS (
SELECT 1 FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND
c.relname='__EFMigrationsHistory'
)
SELECT 1 FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND
c.relname='__EFMigrationsHistory'
)
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (32,060ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT EXISTS (
SELECT 1 FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND
c.relname='__EFMigrationsHistory'
)
Failed executing DbCommand (32,060ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT EXISTS (
SELECT 1 FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND
c.relname='__EFMigrationsHistory'
)
Npgsql.NpgsqlException (0x80004005): Exception while reading from stream
---> System.TimeoutException: Timeout during reading attempt
at Npgsql.Internal.NpgsqlReadBuffer.<Ensure>g__EnsureLong|55_0(NpgsqlReadBuffer buffer, Int32 count, Boolean async, Boolean readingNotifications)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlDataReader.NextResult()
at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteScalar(Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteScalar()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteScalar(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Internal.NpgsqlMigrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Exception while reading from stream
PM>
調べたところ、以下のStackOverflowがでてきた。
コメントに、6543
ではなく、5432
のセッションモードを利用すると解決したとのことでやってみる。
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
- "PostgreSqlConnection": "Host=[Host];Port=6543;Username=[UserName];Password=[Password]"
+ "PostgreSqlConnection": "Host=[Host];Port=5432;Username=[UserName];Password=[Password]"
}
}
ログ
PM> Update-Database
Build started...
Build succeeded.
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (29ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT EXISTS (
SELECT 1 FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND
c.relname='__EFMigrationsHistory'
)
SELECT 1 FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND
c.relname='__EFMigrationsHistory'
)
SELECT 1 FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND
c.relname='__EFMigrationsHistory'
)
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT EXISTS (
SELECT 1 FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND
c.relname='__EFMigrationsHistory'
)
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (25ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE "__EFMigrationsHistory" (
"MigrationId" character varying(150) NOT NULL,
"ProductVersion" character varying(32) NOT NULL,
CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId")
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT EXISTS (
SELECT 1 FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND
c.relname='__EFMigrationsHistory'
)
SELECT 1 FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND
c.relname='__EFMigrationsHistory'
)
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (9ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT "MigrationId", "ProductVersion"
FROM "__EFMigrationsHistory"
ORDER BY "MigrationId";
Microsoft.EntityFrameworkCore.Migrations[20402]
Applying migration '20241110103316_InitialCreate'.
Applying migration '20241110103316_InitialCreate'.
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (20ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE todos (
id integer GENERATED BY DEFAULT AS IDENTITY,
title character varying(100) NOT NULL,
description text NOT NULL,
due_date date NOT NULL,
is_completed boolean NOT NULL,
CONSTRAINT "PK_todos" PRIMARY KEY (id)
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20241110103316_InitialCreate', '8.0.10');
Done.
PM>
問題なく実行できた!
Supabaseでテーブルの確認
Databaseを選択する
確認
todos
テーブルが作成されていることを確認。
画面からの確認
CRUD操作が問題ないことを確認できたのでOK
おまけ
C#ではSupabaseのライブラリを使ってDB操作ができるようだ。
その手順は下記で実施する。
https://supabase.com/docs/reference/csharp/initializing
Supabaseを入れる
https://github.com/supabase-community/supabase-csharp
→ supabase-csharp
は非推奨らしい。
- プロジェクトを右クリック、「NuGetパッケージの管理」を選択する
- 「
Supabase
」をインストールする - インストール完了後、依存関係に 「
Supabase
」が入っていることを確認
Supabase
クライアントでのCRUD処理は書いていないのここまで。
参考
Connecting to your database | supabase Docs
https://supabase.com/docs/guides/database/connecting-to-postgresC# Client Library | supabase Docs
https://supabase.com/docs/reference/csharp/initializingSupabaseでPostgreSQLのDB作成
https://qiita.com/pikimaru/items/5e51d36250c288b8b6dc
おわりに
Supabase
のPostgreSQL
へのDB接続を行った。
今後はこっちの環境をベースに作業をしようと思う。