Top Related Projects
Ruby on Rails
Feature-rich ORM for modern Node.js and TypeScript, it supports PostgreSQL (with JSON and JSONB support), MySQL, MariaDB, SQLite, MS SQL Server, Snowflake, Oracle DB (v6), DB2 and DB2 for IBM i.
ORM for TypeScript and JavaScript. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova and Electron platforms.
Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB
Doctrine Object Relational Mapper (ORM)
The Database Toolkit for Python
Quick Overview
Ecto is a database wrapper and query generator for Elixir. It provides a DSL for writing database queries and a set of tools for working with databases, including migrations, schemas, and changesets. Ecto supports multiple databases, including PostgreSQL, MySQL, and SQLite.
Pros
- Powerful and flexible query DSL
- Support for multiple databases
- Excellent integration with Phoenix framework
- Robust schema and migration system
Cons
- Steep learning curve for beginners
- Can be overkill for simple projects
- Limited support for NoSQL databases
- Performance overhead compared to raw SQL in some cases
Code Examples
- Defining a schema:
defmodule User do
use Ecto.Schema
schema "users" do
field :name, :string
field :email, :string
field :age, :integer
timestamps()
end
end
- Writing a query:
import Ecto.Query
query =
from u in User,
where: u.age > 18,
select: u.name
Repo.all(query)
- Inserting data:
user_changeset = User.changeset(%User{}, %{name: "John", email: "john@example.com", age: 30})
Repo.insert(user_changeset)
- Updating data:
user = Repo.get(User, 1)
changeset = User.changeset(user, %{age: 31})
Repo.update(changeset)
Getting Started
- Add Ecto to your
mix.exs
dependencies:
def deps do
[
{:ecto_sql, "~> 3.9"},
{:postgrex, ">= 0.0.0"}
]
end
-
Run
mix deps.get
to install the dependencies. -
Create a repository module:
defmodule MyApp.Repo do
use Ecto.Repo,
otp_app: :my_app,
adapter: Ecto.Adapters.Postgres
end
- Configure your database in
config/config.exs
:
config :my_app, MyApp.Repo,
database: "my_app_dev",
username: "postgres",
password: "postgres",
hostname: "localhost"
- Create the database and run migrations:
mix ecto.create
mix ecto.migrate
Now you're ready to start using Ecto in your Elixir application!
Competitor Comparisons
Ruby on Rails
Pros of Rails
- Mature ecosystem with extensive libraries and gems
- Convention over configuration, leading to faster development
- Robust built-in testing framework and tools
Cons of Rails
- Performance can be slower compared to Elixir/Phoenix
- Less scalable for highly concurrent applications
- Steeper learning curve for beginners due to "magic" conventions
Code Comparison
Rails (Active Record):
class User < ApplicationRecord
has_many :posts
validates :name, presence: true
end
Ecto:
defmodule User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field :name, :string
has_many :posts, Post
end
def changeset(user, attrs) do
user
|> cast(attrs, [:name])
|> validate_required([:name])
end
end
Rails provides a more concise syntax for defining models and associations, while Ecto offers more explicit control over schema definition and changesets. Rails leverages convention to infer relationships and validations, whereas Ecto requires more explicit declarations but provides greater flexibility in data handling and validation.
Feature-rich ORM for modern Node.js and TypeScript, it supports PostgreSQL (with JSON and JSONB support), MySQL, MariaDB, SQLite, MS SQL Server, Snowflake, Oracle DB (v6), DB2 and DB2 for IBM i.
Pros of Sequelize
- Supports multiple databases (MySQL, PostgreSQL, SQLite, etc.)
- Rich ecosystem with plugins and extensions
- Extensive documentation and large community support
Cons of Sequelize
- Performance can be slower compared to raw SQL queries
- Learning curve for complex queries and associations
- Occasional inconsistencies between different database dialects
Code Comparison
Ecto query example:
from u in User,
where: u.age > 18,
select: u.name
Sequelize query example:
User.findAll({
where: { age: { [Op.gt]: 18 } },
attributes: ['name']
})
Both Ecto and Sequelize are powerful ORM (Object-Relational Mapping) tools for their respective ecosystems. Ecto is designed for Elixir and focuses on composability and explicit queries, while Sequelize is a JavaScript ORM that provides a more traditional ActiveRecord-like interface.
Ecto excels in its integration with Elixir's functional programming paradigm and offers better performance in many scenarios. It also provides more fine-grained control over database interactions.
Sequelize, on the other hand, offers broader database support and a larger ecosystem of plugins. It's more familiar to developers coming from other ORM backgrounds and provides a quicker setup for simple CRUD operations.
The choice between Ecto and Sequelize often depends on the programming language and ecosystem you're working with, as well as specific project requirements and performance needs.
ORM for TypeScript and JavaScript. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova and Electron platforms.
Pros of TypeORM
- Supports multiple databases (MySQL, PostgreSQL, SQLite, etc.) with a single codebase
- Offers both Active Record and Data Mapper patterns
- Provides decorators for easy entity definition and relationship mapping
Cons of TypeORM
- Steeper learning curve due to its extensive feature set
- Performance can be slower compared to Ecto in some scenarios
- Less mature and stable compared to Ecto
Code Comparison
Ecto entity definition:
defmodule User do
use Ecto.Schema
schema "users" do
field :name, :string
field :email, :string
end
end
TypeORM entity definition:
@Entity()
class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
}
Both Ecto and TypeORM provide elegant ways to define database entities, with TypeORM using decorators and Ecto using a schema macro. TypeORM's approach may be more familiar to developers coming from object-oriented backgrounds, while Ecto's functional approach aligns well with Elixir's paradigm. TypeORM offers more flexibility in terms of supported databases and patterns, but Ecto excels in performance and stability within the Elixir ecosystem.
Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB
Pros of Prisma
- Type-safe database access with auto-generated client
- Supports multiple databases (PostgreSQL, MySQL, SQLite, etc.)
- Intuitive schema definition language
Cons of Prisma
- Steeper learning curve for developers new to ORM concepts
- Less flexibility in complex query scenarios
- Potential performance overhead for large-scale applications
Code Comparison
Prisma schema definition:
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
Ecto schema definition:
defmodule User do
use Ecto.Schema
schema "users" do
field :email, :string
field :name, :string
has_many :posts, Post
end
end
Both Prisma and Ecto provide powerful ORM capabilities for their respective ecosystems. Prisma offers a more modern, type-safe approach with auto-generated clients, while Ecto provides greater flexibility and integration with Elixir's functional programming paradigm. The choice between them often depends on the specific project requirements, team expertise, and the target programming language ecosystem.
Doctrine Object Relational Mapper (ORM)
Pros of Doctrine
- Mature and widely adopted in the PHP ecosystem
- Extensive documentation and large community support
- Powerful query builder and DQL (Doctrine Query Language)
Cons of Doctrine
- Steeper learning curve due to complex features and concepts
- Can be slower for simple operations compared to Ecto
- More verbose configuration and setup process
Code Comparison
Ecto query example:
from u in User,
where: u.age > 18,
select: u.name
Doctrine query example:
$qb = $em->createQueryBuilder();
$qb->select('u.name')
->from('User', 'u')
->where('u.age > 18');
Both Ecto and Doctrine are powerful ORM (Object-Relational Mapping) tools for their respective languages. Ecto is designed for Elixir and focuses on simplicity and performance, while Doctrine is a feature-rich ORM for PHP with a long history in enterprise applications.
Ecto's syntax is generally more concise and leverages Elixir's functional programming paradigm. Doctrine, on the other hand, provides a more object-oriented approach with additional features like lazy loading and a rich event system.
While Doctrine offers more out-of-the-box functionality, Ecto's simplicity and performance make it an excellent choice for Elixir developers, especially in projects where speed and scalability are crucial.
The Database Toolkit for Python
Pros of SQLAlchemy
- More mature and widely adopted in the Python ecosystem
- Supports a broader range of databases and SQL dialects
- Offers both ORM and Core (SQL Expression Language) approaches
Cons of SQLAlchemy
- Steeper learning curve due to its extensive feature set
- Can be more verbose and complex for simple use cases
- Performance overhead in some scenarios compared to raw SQL
Code Comparison
Ecto query example:
from u in User,
where: u.age > 18,
select: u.name
SQLAlchemy query example:
session.query(User.name).filter(User.age > 18)
Both Ecto and SQLAlchemy are powerful database tools for their respective languages. Ecto is designed specifically for Elixir and integrates well with the language's functional paradigm. It offers a clean, composable API that aligns with Elixir's pipe operator.
SQLAlchemy, on the other hand, provides a more comprehensive set of features and supports a wider range of databases. It offers greater flexibility in terms of query construction and database interaction, but this can come at the cost of increased complexity.
The choice between the two often depends on the specific language ecosystem (Elixir vs. Python) and the complexity of the database operations required for the project.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Installation
Add :ecto
to the list of dependencies in mix.exs
:
def deps do
[
{:ecto, "~> 3.10"}
]
end
About
Ecto is a toolkit for data mapping and language integrated query for Elixir. Here is an example:
# In your config/config.exs file
config :my_app, ecto_repos: [Sample.Repo]
config :my_app, Sample.Repo,
database: "ecto_simple",
username: "postgres",
password: "postgres",
hostname: "localhost",
port: "5432"
# In your application code
defmodule Sample.Repo do
use Ecto.Repo,
otp_app: :my_app,
adapter: Ecto.Adapters.Postgres
end
defmodule Sample.Weather do
use Ecto.Schema
schema "weather" do
field :city # Defaults to type :string
field :temp_lo, :integer
field :temp_hi, :integer
field :prcp, :float, default: 0.0
end
end
defmodule Sample.App do
import Ecto.Query
alias Sample.{Weather, Repo}
def keyword_query do
query =
from w in Weather,
where: w.prcp > 0 or is_nil(w.prcp),
select: w
Repo.all(query)
end
def pipe_query do
Weather
|> where(city: "Kraków")
|> order_by(:temp_lo)
|> limit(10)
|> Repo.all
end
end
Ecto is commonly used to interact with databases, such as PostgreSQL and MySQL via Ecto.Adapters.SQL (source code). Ecto is also commonly used to map data from any source into Elixir structs, whether they are backed by a database or not.
See the getting started guide and the online documentation for more information. Other resources available are:
-
Programming Ecto, by Darin Wilson and Eric Meadows-Jönsson, which guides you from fundamentals up to advanced concepts
-
The Little Ecto Cookbook, a free ebook by Dashbit, which is a curation of the existing Ecto guides with some extra contents
Usage
You need to add both Ecto and the database adapter as a dependency to your mix.exs
file. The supported databases and their adapters are:
Database | Ecto Adapter | Dependencies |
---|---|---|
PostgreSQL | Ecto.Adapters.Postgres | ecto_sql + postgrex |
MySQL | Ecto.Adapters.MyXQL | ecto_sql + myxql |
MSSQL | Ecto.Adapters.Tds | ecto_sql + tds |
SQLite3 | Ecto.Adapters.SQLite3 | ecto_sqlite3 |
ClickHouse | Ecto.Adapters.ClickHouse | ecto_ch |
ETS   | Etso  | etso |
For example, if you want to use PostgreSQL, add to your mix.exs
file:
defp deps do
[
{:ecto_sql, "~> 3.0"},
{:postgrex, ">= 0.0.0"}
]
end
Then run mix deps.get
in your shell to fetch the dependencies. If you want to use another database, just choose the proper dependency from the table above.
Finally, in the repository definition, you will need to specify the adapter:
respective to the chosen dependency. For PostgreSQL it is:
defmodule MyApp.Repo do
use Ecto.Repo,
otp_app: :my_app,
adapter: Ecto.Adapters.Postgres,
...
Supported Versions
Branch | Support |
---|---|
v3.12 | Bug fixes |
v3.11 | Security patches only |
v3.10 | Security patches only |
v3.9 | Security patches only |
v3.8 | Security patches only |
v3.7 and earlier | Unsupported |
With version 3.0, Ecto API has become stable. Our main focus is on providing bug fixes and incremental changes.
Important links
Running tests
Clone the repo and fetch its dependencies:
$ git clone https://github.com/elixir-ecto/ecto.git
$ cd ecto
$ mix deps.get
$ mix test
Note that mix test
does not run the tests in the integration_test
folder. To run integration tests, you can clone ecto_sql
in a sibling directory and then run its integration tests with the ECTO_PATH
environment variable pointing to your Ecto checkout:
$ cd ..
$ git clone https://github.com/elixir-ecto/ecto_sql.git
$ cd ecto_sql
$ mix deps.get
$ ECTO_PATH=../ecto mix test.all
Running containerized tests
It is also possible to run the integration tests under a containerized environment using earthly:
$ earthly -P +all
You can also use this to interactively debug any failing integration tests using:
$ earthly -P -i --build-arg ELIXIR_BASE=1.8.2-erlang-21.3.8.21-alpine-3.13.1 +integration-test
Then once you enter the containerized shell, you can inspect the underlying databases with the respective commands:
PGPASSWORD=postgres psql -h 127.0.0.1 -U postgres -d postgres ecto_test
MYSQL_PASSWORD=root mysql -h 127.0.0.1 -uroot -proot ecto_test
sqlcmd -U sa -P 'some!Password'
Logo
"Ecto" and the Ecto logo are Copyright (c) 2020 Dashbit.
The Ecto logo was designed by Dane Wesolko.
License
Copyright (c) 2013 Plataformatec
Copyright (c) 2020 Dashbit
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Top Related Projects
Ruby on Rails
Feature-rich ORM for modern Node.js and TypeScript, it supports PostgreSQL (with JSON and JSONB support), MySQL, MariaDB, SQLite, MS SQL Server, Snowflake, Oracle DB (v6), DB2 and DB2 for IBM i.
ORM for TypeScript and JavaScript. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova and Electron platforms.
Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB
Doctrine Object Relational Mapper (ORM)
The Database Toolkit for Python
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot