atlas alternatives and similar packages
Based on the "ORM and Datamapping" category.
Alternatively, view atlas alternatives based on common mentions on social networks and blogs.
-
paper_trail
Track and record all the changes in your database with Ecto. Revert back to anytime in history. -
ecto_psql_extras
Ecto PostgreSQL database performance insights. Locks, index usage, buffer cache hit ratios, vacuum stats and more.
SaaSHub - Software Alternatives and Reviews
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of atlas or a related project?
Popular Comparisons
README
Atlas
Atlas is an Object Relational Mapper for Elixir. (Work in progress. Expect breaking changes)
Current Features
- Postgres Adapter
- Validations
- Persistence
- Schema definitions
- Model query builder
- Auto-generated 'accessor' functions for each field definition
Roadmap
- Extend query builder to support joins
- Add model relationships, ie
belongs_to
,has_many
,has_many through:
- Additional SQL adapters
- Schema migrations
Example Usage:
defmodule User do
use Atlas.Model
@table :users
@primary_key :id
field :id, :integer
field :email, :string
field :is_site_admin, :boolean
field :archived, :boolean
field :state, :string
validates_numericality_of :id
validates_presence_of :email
validates_length_of :email, within: 5..255
validates_format_of :email, with: %r/.*@.*/, message: "Email must be valid"
validates :lives_in_ohio
def lives_in_ohio(record) do
unless record.state == "OH", do: {:state, "You must live in Ohio"}
end
def admins do
where(archived: false) |> where(is_site_admin: true)
end
def admin_with_email(email) do
admins |> where(email: email)
end
end
iex> admin = Repo.first User.admin_with_email("[email protected]")
%User{id: 5, email: "[email protected]", archived: false, is_site_admin: true...}
Query Builder
Examples
iex> User.where(email: "[email protected]")
|> User.where("state IS NOT NULL")
|> User.order(update_at: :asc)
|> Repo.all
[%User{id: 5, archived: true, is_site_admin: false...}, %User{id: 5, archived: true, is_site_admin: false...}]
iex> user = User.where(email: "[email protected]") |> Repo.first
%User{id: 5, archived: false, is_site_admin: false...}
iex> user.email
[email protected]
iex> User.where(archived: true)
|> User.order(updated_at: :desc)
|> Repo.first
%User{id: 5, archived: true, is_site_admin: false...}
Queries are composable
defmodule UserSearch do
import User
def perform(options) do
is_admin = Keyword.get options, :is_site_admin, false
email = Keyword.get options, :email, nil
scope = User.scoped
scope = scope |> where(is_site_admin: is_admin)
if email, do: scope = scope |> where(email: email)
scope |> Repo.all
end
end
iex> UserSearch.perform(is_site_admin: true, email: "[email protected]")
[%User{email: "[email protected]"}]
Persistence
Atlas uses the Repository pattern to decouple persistence from behavior, as well as allow multiple database connections
to different repositories for a robust and flexible persistence layer. When creating/updating/destroying data,
a list of behaviors must be included to run validation callbacks against for the Repo to proceed or halt with requested
actions via the as:
option.
Examples
defmodule User do
use Atlas.Model
@table :users
@primary_key :id
field :age, :integer
field :name, :string
validates_numericality_of :age, within: 1..150
validates_presence_of :name
end
defmodule Manager do
use Atlas.Validator
validates_numericality_of :age, greater_than_or_equal: 21, message: "managers must be at least 21"
end
iex> Repo.create(User, [age: 12, name: "Dilbert"], as: User)
{:ok, %User{age: 12...}}
iex> user = Repo.first(User)
iex> Repo.update(user, [age: 18], as: [User, Manager])
{:error, %User{age: 18...}, ["managers must be at least 21"]}
iex> Repo.create(User, [age: 0, name: "Chris"], as: User)
{:error, %User{age: 0..}, ["age must be between 1 and 150"]}
Accessors
Accessors for assigning and retrieving model attributes are automatically defined from the shema field definitions.
By default, Accessors are simply pass-throughs to the raw record setter and getter
values; however, accessors can be overriden by the module for extended behavior
and transformations before writing to, or after reading from the database.
assign
functions transform attributes when creating a new Struct via Model.new
and
before running model callbacks such as validations.
Example attribute assignment:
defmodule User do
use Atlas.Model
field :email, :string
field :name, :string
def assign(user, :email, value), do: user.update(email: String.downcase(value))
end
iex> User.assign(user, :email, "[email protected]")
User[email: "[email protected]"]
iex> User.new(email, "[email protected]")
User[email: "[email protected]"]
Example attribute retrieval:
defmodule User do
use Atlas.Model
field :email, :string
field :name, :string
def email(user), do: user.email |> String.upcase
end
iex> user = User.new(email: "[email protected]")
iex> User.email(user)
[email protected]
Auto-generated finders
with_[field name]
functions are automatically generated for all defined fields.
For example, a User module with a field :email, :string
definition would include a User.with_email
function
that returns the first record matching that field from the database.
Validation Support
iex> user = User.new(email: "invalid")
%User{id: nil, email: "invalid", is_site_admin: nil...}
iex> User.validate user
{:error, %User{newsletter_updated_at: ...}, [email: "Email must be valid", email: "_ must be between 5 and 255 characters",
email: "_ must not be blank"]}
iex> User.full_error_messages user
["Email must be valid","email must be between 5 and 255 characters","email must not be blank","id must be a valid number"]
Repo Configuration
Define at least one Repository in your project that uses Atlas.Repo with a supported adapter.
Your Repo simply needs to be provide config
functions for :dev
, :test
, and :prod
environments.
After defining your repo, start its process within your application.
defmodule Repo do
use Atlas.Repo, adapter: Atlas.Adapters.Postgres
def config(:dev) do
[
database: "",
username: "",
password: "",
host: "",
pool: 5,
log_level: :debug
]
end
def config(:test) do
[
database: "",
username: "",
password: "",
host: "",
pool: 5,
log_level: :debug
]
end
def config(:prod) do
[
database: "",
username: "",
password: "",
host: "",
pool: 5,
log_level: :warn
]
end
end
Repo.start_link
Testing
Testing requires a lib/atlas/repos/dev_repo.ex
to exist. Here's an example:
defmodule Repo do
use Atlas.Repo, adapter: Atlas.Adapters.Postgres
def config(:dev) do
[
database: "",
username: "",
password: "",
host: "localhost",
pool: 5,
log_level: :debug
]
end
def config(:test) do
[
database: "atlas_test",
username: "chris",
password: "",
host: "localhost",
pool: 5,
log_level: :debug
]
end
def config(:prod) do
[
database: "",
username: "",
password: "",
host: "",
pool: 5,
log_level: :warn
]
end
end