はじめに
PostGIS拡張機能を許可したあと、テーブル作成した際geography(POINT)型をsupabaseが認識できないようでunknown型になってしまい、その影響でmap関数が使用できずそちらの解決方法について備忘録も兼ねて記事にします。
解決方法
型を作成しその型を明示する
手順
PostGISはドキュメントどおりに許可しています。
.SQL
create extension postgis with schema "extensions";
【テーブル作成】
.SQL
create table if not exists public.post_locations (
post_id int not null references posts(id) on delete cascade,
location geography(POINT) not null, // geography型
PRIMARY KEY(post_id)
);
次に位置情報を取得するための関数をSupabase DatabaseのUI functionsを利用しましたが、エラーで作成ができずSQLで作成することにしました。
.SQL
create or replace function get_all_post_coordinates() // 全て取得するので引数なし
returns table (
post_id integer,
latitude double precision,
longitude double precision
)
language sql
as $$
select
post_id,
ST_Y(location::geometry) as latitude, // (locationカラムの値をgemetryに変換しそれをST_Yに渡す)それをlatitudeとする
ST_X(location::geometry) as longitude
from post_locations;
$$;
databaseファイルへ反映
.terminal
npx supabase gen types typescript --project-id "ここにprojectIDを入力" --schema public > utils/supabase-database.ts
下記のようにunknown型になります
supabase-database.ts
export type Database = {
public: {
Tables: {
post_locations: {
Row: {
location: unknown
post_id: number
}
Insert: {
location: unknown
post_id: number
}
Update: {
location?: unknown
post_id?: number
}
Relationships: [
{
foreignKeyName: "post_locations_post_id_fkey"
columns: ["post_id"]
isOneToOne: true
referencedRelation: "posts"
referencedColumns: ["id"]
},
]
}
atomと型を作成
.tsx
export type PostLocation = {
post_id: number;
latitude: number;
longitude: number;
};
export const locationAtom = atom<PostLocation[]>([]);
ここでset関数に渡すdataに型を明示する
.tsx
useEffect(() => {
const fetchData = async () => {
try {
const { data, error } = await supabase
.rpc('get_all_post_coordinates') // 関数実行
if (error) throw error;
if (data) setlocationData(data as PostLocation[]); // ここでdataがPostLocation[]であることを明示
} catch (error) {
console.error('データ取得失敗', error);
}
};
fetchData();
}, []);
///////////////////////////
{locationData?.map((location) => {
return (<Marker
key={location.post_id}
position={[location.latitude, location.longitude]}
></Marker>)
})}
<Marker
参考
おわりに
Databaseのfunctionについても勉強になりました。