A Clojure library for managing DynamoDB table migrations and keeping table definitions in sync between local and production environments.
Highly inspired in migratus and how it is easy to use it.
Add to your deps.edn:
;; From Clojars
{:deps {org.clojars.morita/dynatus {:mvn/version "0.1.0"}}}
;; Or from GitHub
{:deps {dynatus/dynatus {:git/url "https://github.com/yourusername/dynatus"
:git/sha "LATEST_SHA"}}}
(require '[dynatus.core :as dynatus]
'[cognitect.aws.client.api :as aws])
;; Create a DynamoDB client using AWS SDK
(def dynamo-client (aws/client {:api :dynamodb
:region "us-east-1"}))
;; Run migrations from resources/dynamo directory
(dynatus/migrate {:client dynamo-client
:path "resources/dynamo"})
The library is designed to work with any Cognitect AWS DynamoDB client, giving you full control over client configuration.
Create .edn files in your migrations directory:
;; resources/dynamo/users.edn
{:TableName "users"
:KeySchema [{:AttributeName "user_id"
:KeyType "HASH"}]
:AttributeDefinitions [{:AttributeName "user_id"
:AttributeType "S"}
{:AttributeName "email"
:AttributeType "S"}]
:BillingMode "PAY_PER_REQUEST"
:GlobalSecondaryIndexes [{:IndexName "email-index"
:KeySchema [{:AttributeName "email"
:KeyType "HASH"}]
:Projection {:ProjectionType "ALL"}}]
:StreamSpecification {:StreamEnabled true
:StreamViewType "NEW_AND_OLD_IMAGES"}
:Tags [{:Key "Environment"
:Value "production"}]}
For local development, you can configure your AWS client to connect to local DynamoDB:
(require '[cognitect.aws.client.api :as aws]
'[cognitect.aws.interceptors :as interceptors])
;; Define interceptor for local DynamoDB
(defmethod interceptors/modify-http-request "dynamodb"
[service http-request]
(-> http-request
(assoc :scheme :http
:server-port 8000
:server-name "localhost")
(assoc-in [:headers "host"] "localhost:8000")))
;; Create client - interceptor will redirect to local
(def local-client (aws/client {:api :dynamodb
:region "us-east-1"}))
(require '[dynamigrate.test-fixtures :as fixtures])
(use-fixtures :each fixtures/with-dynamodb-container)
(deftest my-test
(testing "DynamoDB operations"
;; Use fixtures/*test-client* which is automatically connected
;; to a DynamoDB container
(let [client fixtures/*test-client*]
;; Your test code here
)))
# Run all tests
clojure -M:test -m kaocha.runner
# Run with specific test
clojure -M:test -m kaocha.runner --focus dynamigrate.core-test
dynamigrate/
├── deps.edn # Dependencies
├── src/
│ └── dynamigrate/
│ ├── core.clj # Main migration logic
│ ├── loader.clj # Table definition loader
│ ├── diff.clj # Table comparison logic
│ └── apply.clj # Apply migrations
├── test/
│ └── dynamigrate/
│ ├── core_test.clj # Integration tests
│ ├── test_fixtures.clj # Testcontainers setup
│ └── test_client.clj # Test-specific client with interceptors
└── resources/
└── dynamo/ # Table definitions
├── users.edn
└── orders.edn
IN_DOCKER - Set to "true" when running in DockerDYNAMODB_LOCAL_ENDPOINT - Override local DynamoDB endpointAWS_PROFILE - AWS profile for credentials# Build the JAR file
clojure -X:jar
# This creates target/dynamigrate.jar
# Install to local Maven repository (~/.m2)
clojure -X:install
First, configure your Clojars credentials in ~/.m2/settings.xml:
<settings>
<servers>
<server>
<id>clojars</id>
<username>your-username</username>
<password>your-deploy-token</password>
</server>
</servers>
</settings>
Then deploy:
# Deploy to Clojars
clojure -X:deploy
# For snapshot versions
clojure -X:deploy :version '"0.1.0-SNAPSHOT"'
Once deployed to Clojars:
;; deps.edn
{:deps {net.clojars.rafael-campo/dynamigrate {:mvn/version "0.1.0"}}}
;; Leiningen project.clj
[net.clojars.rafael-campo/dynamigrate "0.1.0"]
The project uses GitHub Actions for automated testing and deployment:
ci.yml - Lightweight CI for every push/PR
test.yml - Comprehensive test suite
deploy_clojars.yml - Automated deployment
v0.1.0)jlesquembre/clojars-publish-action@v2 for deploymentCLOJARS_USERNAME and CLOJARS_TOKEN secrets# Run all tests
make test
# Run tests with specific Java version
JAVA_HOME=/path/to/java11 make test
# Run with verbose output
clojure -M:test -m kaocha.runner --reporter documentation
# Run specific test namespace
clojure -M:test -m kaocha.runner --focus dynamigrate.core-test
git commit -am "Prepare release v0.1.0"git tag v0.1.0git push origin main --tagsjlesquembre/clojars-publish-actionYou can also trigger a deployment manually from GitHub Actions:
0.1.0)For automated deployment, configure these secrets in your GitHub repository:
CLOJARS_USERNAME: Your Clojars usernameCLOJARS_TOKEN: Your Clojars deploy token (get from Clojars → Deploy Tokens)This project uses jlesquembre/clojars-publish-action@v2 for automated Clojars deployment. This action:
The library includes a GitHub Actions workflow for automatic deployment to Clojars when a new release is created.
CLOJARS_TOKENCopyright © 2025 MoritaHR
Distributed under the MIT License.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |