데이터베이스 연결하기
앱 전용 Postgres DB를 켜고, 코드에서 읽고 쓰고, 콘솔에서 표로 확인하는 방법이에요. 템플릿 앱은 이미 켜져 있어요.
주문 목록이나 회원 정보처럼 앱이 다루는 데이터는 앱 전용 데이터베이스에 저장해요.
템플릿으로 만든 앱은 이미 켜져 있어서, 바로 표를 만들고 읽고 쓰면 돼요.
만들어지는 건 표준 Postgres예요. 그래서 postgres · pg · Prisma · Drizzle 등 평소 쓰던 도구를 그대로 써요.
템플릿으로 만든 앱이라면
Next.js · Astro 템플릿은 아래가 이미 되어 있어요.
| 준비된 것 | 내용 |
|---|---|
axhub.yaml 선언 | database: engine: postgres가 들어 있어요 |
| 접속 코드 | lib/db.ts의 db()가 접속을 맡아요 |
| 표 만들기 | 같은 파일의 ensureSchema()에 CREATE TABLE을 적어요 |
import { db, ensureSchema } from '@/lib/db';
await ensureSchema();
const rows = await db()`SELECT * FROM todos WHERE user_key = ${userKey}`;값을 ${...}로 넘기면 알아서 안전하게 처리돼요 — 문자열을 직접 이어 붙이지 마세요.
표를 새로 만들거나 컬럼을 늘리려면 ensureSchema() 안의 CREATE TABLE IF NOT EXISTS 블록을 늘리면 돼요. 평범한 SQL이에요.
내 컴퓨터에서 개발할 때
템플릿에 Postgres를 띄우는 명령이 들어 있어요.
npm run db:up # 로컬 Postgres 시작
npm run db:reset # 데이터까지 지우고 새로 시작.env.local의 DATABASE_URL이 이 로컬 DB를 가리켜요. 배포하면 AxHub가 넣어 주는 값으로 바뀌고, 코드는 그대로예요.
직접 켜는 경우
템플릿을 안 썼다면 axhub.yaml에 두 줄을 넣고 배포해요.
database:
engine: postgresengine에는 현재 postgres만 넣을 수 있어요. 파일을 고치는 대신 터미널에서 켜려면 axhub apps raw-db enable --app <앱> --execute도 같은 효과예요.
다음 배포에서 앱 전용 DB가 만들어지고, 접속 정보가 환경변수로 들어와요.
| 환경변수 | 용도 |
|---|---|
DATABASE_URL | 평소 데이터를 읽고 쓸 때 쓰는 주소예요. 접속을 모아서 관리해 주는 중계기(커넥션 풀러)를 거쳐요 |
DIRECT_DATABASE_URL | 표 구조를 바꾸는 작업(마이그레이션)처럼, 중계기 없이 직접 붙어야 하는 일에 써요 |
import { Pool } from 'pg';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const { rows } = await pool.query('SELECT * FROM orders WHERE done = $1', [false]);datasource db {
provider = "postgresql"
url = env("DATABASE_URL") // 쿼리
directUrl = env("DIRECT_DATABASE_URL") // 마이그레이션
}prepare: false가 필요할 수 있어요. DATABASE_URL이 거치는 중계기는 prepared statement를 지원하지 않아서, postgres 같은 드라이버는 이 옵션을 꺼야 동작해요. 로컬에서는 잘 되다가 배포 후에만 실패한다면 이걸 확인하세요.
postgres(process.env.DATABASE_URL, { prepare: false })production(실제 서비스)과 staging(시험용)은 서로 다른 DB를 받아요. 각 환경에 배포하면 그 환경의 DB가 만들어지고, 서로의 데이터가 섞이지 않아요.
콘솔에서 표로 보기
데이터가 실제로 어떻게 쌓였는지는 앱 콘솔 → 리소스 탭 → 테이블에서 그대로 조회할 수 있어요.
터미널에서는 이렇게 봐요.
axhub tables db-list --app demo # 테이블 목록
axhub tables db-rows orders --app demo # 행 조회
axhub tables db-rows orders --app demo --environment staging앱 코드 안에서는 SDK로 sdk.apps.rawDb.tables(appId) · sdk.apps.rawDb.tableRows(appId, 'orders')를 부르면 같은 걸 읽어요 — SDK 설정은 SDK 설치하기에서 해요.
세 곳 모두 읽기 전용이라 여기서 데이터를 고칠 수는 없어요. 그리고 앱 소유자가 열람 정책으로 잠가 둔 앱이라면, 관리자라도 콘솔 · 터미널에서 행 내용 열람이 제한될 수 있어요.
알아두면 좋은 것
- 화면만 있는 앱에는 못 붙여요 — 정적 호스팅 앱은 계속 돌고 있는 서버가 없어서 접속 정보를 넣을 곳이 없어요. 선언한 채 배포하면 배포가 명확히 실패해요.
- 선언을 지워도 DB는 사라지지 않아요 — 데이터와 주입은 유지돼요. 정말 끄려면
axhub apps raw-db disable --app <앱> --execute를 쓰세요. 이때도 표와 데이터는 그대로 남고 접속만 끊겨요 — 다시 켜면 새 비밀번호로 접속 정보가 다시 들어와요. DATABASE_URL은 직접 덮어쓸 수 없어요 — DB를 켠 앱에서는 AxHub가 넣어 주는 값이 항상 이겨요. 같은 이름으로 저장한 환경변수는 무시돼요. (DB를 켜지 않은 앱이라면 외부 DB 주소를 자유롭게 넣어도 돼요.)- 이미 떠 있는 앱에는 소급 주입되지 않아요 — 켠 뒤 첫 배포부터 환경변수가 들어가요.
- SDK에는 행 쓰기 API가 없어요 — 쓰기는 앱 런타임의
DATABASE_URL로 해요.
이렇게 보이면 성공
배포가 끝나고, 앱 콘솔 → 리소스 탭 → 테이블에서 내 앱의 테이블과 행이 표로 보이면 성공이에요. 앱 코드가 DATABASE_URL로 읽고 쓴 내용이 그대로 나타나요.
다음은 스토리지 연결하기에서 이미지 · 첨부파일 둘 곳을 만들어요.