设想这样的场景,之前有个Rails应用,使用的MySQL数据库,现在使用Phoenix进行重构,其中的User表还是MySQL的,但是你需要添加Favorite记录,并且使用新的PostgreSQL。
也就是说,我们要将Phoenix应用连接两个不同的数据库,并且这两个数据库还是不同种类的。
很高兴告诉大家,Ecto能非常容易的做到这点!
首先,在config/config.exs
添加一个新的config字段,为应用连接的另一个Repo。
use Mix.Config
config :my_app, MyApp.LegacyRepo,
adapter: Ecto.Adapters.MySQL,
database: "legacy_db",
username: "username",
password: "somethingsecret",
hostname: "legacy.mysite.com"
config :my_app, MyApp.NewRepo,
adapter: Ecto.Adapters.Postgres,
username: "username",
password: "somethingsecret",
database: "new_db",
hostname: "newhotness.mysite.com"
config :my_app, ecto_repos: [MyApp.LegacyRepo, MyApp.NewRepo]
添加完配置文件之后,我们还得保证监控这两个Repo。
在lib/my_app.ex
中,开启对两个Repo的监控。
defmodule ExistingDb do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
supervisor(MyApp.LegacyRepo, []), # <-- our addition
supervisor(MyApp.NewRepo, []) # <-- our addition
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
end
最后,我们需要创建Repo的模块,为了简明起见,我们把两个模块卸载一个文件lib/repos.ex
里。
defmodule MyApp.LegacyRepo do
use Ecto.Repo, otp_app: :my_app
end
defmodule MyApp.NewRepo do
use Ecto.Repo, otp_app: :my_app
end
为了项目完整性,我们来创建两个非常基本的schema,一个是User,一个是Favorite,它们是一对多的关系。
在lib/user.ex
添加:
defmodule User do
use Ecto.Schema
schema "users" do
field :username, :string
has_many :favorites, Favorite
timestamps
end
end
在lib/favorite.ex
添加:
defmodule Favorite do
use Ecto.Schema
schema "favorites" do
field :value, :string
belongs_to :user, User
timestamps
end
end
最后我们使用iex -S mix phoenix.server
来测试:
# a little setup
iex> import Ecto.Query
# let's grab a User from the legacy db
iex> user = MyApp.LegacyRepo.get_by(User, %{username: "Geo"})
# now that we have our user from the legacy database, let's find their
# favorites in the new database
iex> favorites = MyApp.NewRepo.all from fav in Favorite,
where: fav.user_id == ^user.id
Refs
http://geoffreylessel.com/2016/connecting-to-multiple-databases-with-ecto/