Skip to content

Commit 755b8a9

Browse files
Add SQLAlchemy example and migration files for ClickHouse and PostgreSQL (#220)
1 parent fccddec commit 755b8a9

File tree

8 files changed

+128
-0
lines changed

8 files changed

+128
-0
lines changed

projects/sqlalchemy/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# SQLAlchemy example
2+
3+
This folder contains a minimal SQLAlchemy example used with Atlas. The README lists quick setup steps and the Atlas commands commonly used for generating migration files for different dialects.
4+
5+
Prerequisites
6+
- Python.
7+
- `atlas` CLI available on your PATH.
8+
9+
Quick setup
10+
11+
1. Create and activate a virtual environment inside the project:
12+
13+
```bash
14+
python -m venv .venv
15+
source .venv/bin/activate
16+
```
17+
18+
2. Install Python dependencies from the provided `requirements.txt`:
19+
20+
```bash
21+
pip install -r requirements.txt
22+
```
23+
24+
Running Atlas migrate diffs
25+
26+
From this directory you can run Atlas to generate migration files for different dialects using the `atlas migrate diff` command. Examples:
27+
28+
```bash
29+
# Migration for ClickHouse
30+
atlas migrate diff --env sqlalchemy --var dialect=clickhouse
31+
32+
# Migration for PostgreSQL
33+
atlas migrate diff --env sqlalchemy --var dialect=postgresql
34+
```

projects/sqlalchemy/app/models.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from sqlalchemy import ForeignKey, String
2+
from sqlalchemy.orm import Mapped, mapped_column, relationship, DeclarativeBase
3+
from clickhouse_sqlalchemy import engines
4+
5+
6+
class Base(DeclarativeBase):
7+
pass
8+
9+
10+
class User(Base):
11+
__tablename__ = "user_account"
12+
__table_args__ = (engines.MergeTree(order_by="id"),)
13+
14+
id: Mapped[int] = mapped_column(primary_key=True)
15+
name: Mapped[str] = mapped_column(String(30))
16+
fullname: Mapped[str | None] = mapped_column(String(30))
17+
addresses: Mapped[list["Address"]] = relationship(
18+
back_populates="user", cascade="all, delete-orphan"
19+
)
20+
21+
22+
class Address(Base):
23+
__tablename__ = "address"
24+
__table_args__ = (engines.MergeTree(order_by="id"),)
25+
26+
id: Mapped[int] = mapped_column(primary_key=True)
27+
email_address: Mapped[str] = mapped_column(String(30))
28+
user_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
29+
user: Mapped["User"] = relationship(back_populates="addresses")

projects/sqlalchemy/atlas.hcl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
variable "dialect" {
2+
type = string
3+
}
4+
5+
locals {
6+
dev_url = {
7+
mysql = "docker://mysql/8/dev"
8+
postgresql = "docker://postgres/15"
9+
sqlite = "sqlite://?mode=memory&_fk=1"
10+
mssql = "docker://sqlserver/2022-latest"
11+
clickhouse = "docker://clickhouse/23.11/dev"
12+
}[var.dialect]
13+
}
14+
15+
data "external_schema" "sqlalchemy" {
16+
program = [
17+
"atlas-provider-sqlalchemy",
18+
"--path", "app",
19+
"--dialect", var.dialect,
20+
]
21+
}
22+
23+
env "sqlalchemy" {
24+
src = data.external_schema.sqlalchemy.url
25+
dev = local.dev_url
26+
migration {
27+
dir = "file://migrations/${var.dialect}"
28+
}
29+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- Create "address" table
2+
CREATE TABLE `address` (
3+
`id` Int32,
4+
`email_address` FixedString(30),
5+
`user_id` Int32
6+
) ENGINE = MergeTree
7+
PRIMARY KEY (`id`) ORDER BY (`id`) SETTINGS index_granularity = 8192;
8+
-- Create "user_account" table
9+
CREATE TABLE `user_account` (
10+
`id` Int32,
11+
`name` FixedString(30),
12+
`fullname` FixedString(30)
13+
) ENGINE = MergeTree
14+
PRIMARY KEY (`id`) ORDER BY (`id`) SETTINGS index_granularity = 8192;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
h1:YuQ5NkluwWB2JuhWWycm2nE57WQMei0kUJdR44wmZl8=
2+
20251008091308.sql h1:AqkDYUGT5nmGPSxCIT5W/+gE7itlYq/Rkop98gmzTD4=
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-- Create "user_account" table
2+
CREATE TABLE "public"."user_account" (
3+
"id" serial NOT NULL,
4+
"name" character varying(30) NOT NULL,
5+
"fullname" character varying(30) NULL,
6+
PRIMARY KEY ("id")
7+
);
8+
-- Create "address" table
9+
CREATE TABLE "public"."address" (
10+
"id" serial NOT NULL,
11+
"email_address" character varying(30) NOT NULL,
12+
"user_id" integer NOT NULL,
13+
PRIMARY KEY ("id"),
14+
CONSTRAINT "address_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."user_account" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION
15+
);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
h1:9kuDGlVM39qg/yzzmxkvR5BqE+r2jJm9Yotsx3u6S6A=
2+
20251008091314.sql h1:4FGUQLXUkLg5NLUehNvPCNG9+EsLCNeqyqYtaNEi7UU=
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
sqlalchemy>=2.0.43
2+
clickhouse_sqlalchemy>=0.3.2
3+
atlas-provider-sqlalchemy>=0.4.1

0 commit comments

Comments
 (0)