Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Working With Legacy Databases in Ecto - ElixirConf 2017

Working With Legacy Databases in Ecto - ElixirConf 2017

Often when starting an Elixir or Phoenix project that is data-backed, there is an existing database that you need to interact with. There are plenty of tutorials about getting started with Ecto in a green project, but how do you take a legacy database and get it working in your new application? We'll explore normal situations all the way to crazy ones like weird foreign keys and even dealing with multiple databases simultaneously!

Youtube link: https://youtu.be/3W2dMOQL2CM

Geoffrey Lessel

September 07, 2017
Tweet

More Decks by Geoffrey Lessel

Other Decks in Programming

Transcript

  1. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel GOALS You

    should be able to seamlessly use an existing database
  2. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel Non-integer primary

    keys d6286e95-47e9-48d3-ace9-a344d622d0ee THE PROBLEM
  3. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel THE SOLUTION

    Code examples and slides can be found at geoffreylessel.com/elixirconf2017
  4. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel THE SOLUTION

    Ergast Motor Racing Database http://ergast.com/mrd/
  5. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defp deps

    do [ {:phoenix, "!~> 1.3.0"}, {:phoenix_pubsub, "!~> 1.0"}, {:phoenix_ecto, "!~> 3.2"}, {:phoenix_html, "!~> 2.10"}, {:phoenix_live_reload, "!~> 1.0", only: :dev}, {:react_phoenix, "!~> 0.4.0"}, {:ecto, "!~> 2.2.0-rc.1", override: true}, {:gettext, "!~> 0.11"}, {:cowboy, "!~> 1.0"}, {:mariaex, !"> 0.0.0"} ] end The Solution Use Ecto 2.2 for Existing tables and data mix.exs
  6. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defp deps

    do [ {:phoenix, "!~> 1.3.0"}, {:phoenix_pubsub, "!~> 1.0"}, {:phoenix_ecto, "!~> 3.2"}, {:phoenix_html, "!~> 2.10"}, {:phoenix_live_reload, "!~> 1.0", only: :dev}, {:react_phoenix, "!~> 0.4.0"}, {:ecto, "!~> 2.2.0-rc.1", override: true}, {:gettext, "!~> 0.11"}, {:cowboy, "!~> 1.0"}, {:mariaex, !"> 0.0.0"} ] end The Solution Use Ecto 2.2 for Existing tables and data mix.exs
  7. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel THE SOLUTION

    for Existing tables and data mix ecto.dump mix ecto.load
  8. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel THE SOLUTION

    for Existing tables and data https://elixirforum.com/t/schema-file-for-phoenix-migrations/1590/2
  9. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defp aliases

    do [ "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], "ecto.reset": ["ecto.drop", "ecto.setup"], "ecto.migrate": ["ecto.migrate", "ecto.dump"], "test": ["ecto.create !--quiet", "ecto.migrate", "test"] ] end The Solution mix ecto.dump mix ecto.load for Existing tables and data for Existing tables and data mix.exs
  10. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defp aliases

    do [ "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], "ecto.reset": ["ecto.drop", "ecto.setup"], "ecto.migrate": ["ecto.migrate", "ecto.dump"], "test": ["ecto.create !--quiet", "ecto.migrate", "test"] ] end The Solution mix ecto.dump mix ecto.load for Existing tables and data for Existing tables and data mix.exs
  11. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel THE SOLUTION

    for Funky column name formats source: :columnName
  12. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ |

    Field | Type | Null | Key | Default | Extra | +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ | raceId | int(11) | NO | PRI | NULL | auto_increment | | year | int(11) | NO | | 0 | | | round | int(11) | NO | | 0 | | | circuitId | int(11) | NO | | 0 | | | name | varchar(255) | NO | | | | | date | date | NO | | 0000-00-00 | | | time | time | YES | | NULL | | | url | varchar(255) | YES | UNI | NULL | | +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ 8 rows in set (0.01 sec) The Solution source: :columnName for Funky column name formats
  13. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ |

    Field | Type | Null | Key | Default | Extra | +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ | raceId | int(11) | NO | PRI | NULL | auto_increment | | year | int(11) | NO | | 0 | | | round | int(11) | NO | | 0 | | | circuitId | int(11) | NO | | 0 | | | name | varchar(255) | NO | | | | | date | date | NO | | 0000-00-00 | | | time | time | YES | | NULL | | | url | varchar(255) | YES | UNI | NULL | | +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ 8 rows in set (0.01 sec) The Solution source: :columnName for Funky column name formats
  14. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string end end The Solution source: :columnName for Funky column name formats +—————!!-+--------------+ | Field | Type | +----------!!-+--------------+ | raceId | int(11) | | year | int(11) | | round | int(11) | | circuitId | int(11) | | name | varchar(255) | | date | date | | time | time | | url | varchar(255) | +----------!!-+--------------+ 8 rows in set (0.01 sec)
  15. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit end end The Solution source: :columnName for Funky column name formats
  16. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit end end The Solution source: :columnName for Funky column name formats
  17. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit end end The Solution source: :columnName for Funky column name formats circuit_id
  18. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end The Solution source: :columnName for Funky column name formats
  19. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end The Solution source: :columnName for Funky column name formats
  20. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ |

    Field | Type | Null | Key | Default | Extra | +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ | raceId | int(11) | NO | PRI | NULL | auto_increment | | year | int(11) | NO | | 0 | | | round | int(11) | NO | | 0 | | | circuitId | int(11) | NO | | 0 | | | name | varchar(255) | NO | | | | | date | date | NO | | 0000-00-00 | | | time | time | YES | | NULL | | | url | varchar(255) | YES | UNI | NULL | | +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ 8 rows in set (0.01 sec) The Solution source: :columnName for Funky column name formats
  21. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ |

    Field | Type | Null | Key | Default | Extra | +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ | raceId | int(11) | NO | PRI | NULL | auto_increment | | year | int(11) | NO | | 0 | | | round | int(11) | NO | | 0 | | | circuitId | int(11) | NO | | 0 | | | name | varchar(255) | NO | | | | | date | date | NO | | 0000-00-00 | | | time | time | YES | | NULL | | | url | varchar(255) | YES | UNI | NULL | | +----------!!-+-------------!!-+-----!!-+-!!---!!-+-----------!!-+----------------+ 8 rows in set (0.01 sec) The Solution source: :columnName for Funky column name formats
  22. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :id, source: :raceId} schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end The Solution source: :columnName for Funky column name formats
  23. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :id, source: :raceId} schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end The Solution source: :columnName for Funky column name formats
  24. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :id, source: :raceId} schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end The Solution source: :columnName for Funky column name formats {fieldname, type, options}
  25. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :id, source: :raceId} schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end The Solution source: :columnName for Funky column name formats
  26. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.API.Race

    do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :id, source: :raceId} schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end The Solution @primary_key for Non-integer primary keys
  27. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @primary_key for Non-integer primary keys defmodule F1Saver.API.Race do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :id, source: :raceId} schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end {fieldname, type, options}
  28. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @primary_key for Non-integer primary keys defmodule F1Saver.API.Race do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :binary_id, source: :raceId} schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end {fieldname, type, options}
  29. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @foreign_key_type for Non-integer primary keys defmodule F1Saver.API.Race do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :binary_id, source: :raceId} @foreign_key_type :binary_id schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end
  30. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @foreign_key_type for Non-integer primary keys defmodule F1Saver.API.Race do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :binary_id, source: :raceId} @foreign_key_type :binary_id schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, source: :circuitId end end
  31. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel mysql> describe

    lapTimes; +-------------!!-+-------------!!-+-----!!-+-!!---!!-+--------!!-+-------+ | Field | Type | Null | Key | Default | Extra | +-------------!!-+-------------!!-+-----!!-+-!!---!!-+--------!!-+-------+ | raceId | int(11) | NO | PRI | NULL | | | driverId | int(11) | NO | PRI | NULL | | | lap | int(11) | NO | PRI | NULL | | | position | int(11) | YES | | NULL | | | time | varchar(255) | YES | | NULL | | | milliseconds | int(11) | YES | | NULL | | +-------------!!-+-------------!!-+-----!!-+-!!---!!-+--------!!-+-------+ 6 rows in set (0.01 sec) The Solution @primary_key for no primary key
  32. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @primary_key for no primary key defmodule F1Saver.API.Lap do use Ecto.Schema alias F1Saver.API.{Driver, Race} @primary_key false schema "lapTimes" do field :lap, :integer field :time, :string field :race_id, :integer, source: :raceId field :driver_id, :integer, source: :driverId belongs_to :race, Race, foreign_key: :raceId, define_field: false belongs_to :driver, Driver, foreign_key: :driverId, define_field: false end end
  33. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @primary_key for no primary key defmodule F1Saver.API.Lap do use Ecto.Schema alias F1Saver.API.{Driver, Race} @primary_key false schema "lapTimes" do field :lap, :integer field :time, :string field :race_id, :integer, source: :raceId field :driver_id, :integer, source: :driverId belongs_to :race, Race, foreign_key: :raceId, define_field: false belongs_to :driver, Driver, foreign_key: :driverId, define_field: false end end
  34. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @primary_key for no primary key defmodule F1Saver.API.Lap do use Ecto.Schema alias F1Saver.API.{Driver, Race} @primary_key false schema "lapTimes" do field :lap, :integer field :time, :string field :race_id, :integer, source: :raceId field :driver_id, :integer, source: :driverId belongs_to :race, Race, foreign_key: :raceId, define_field: false belongs_to :driver, Driver, foreign_key: :driverId, define_field: false end end
  35. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @primary_key for no primary key defmodule F1Saver.API.Lap do use Ecto.Schema alias F1Saver.API.{Driver, Race} @primary_key false schema "lapTimes" do field :lap, :integer field :time, :string field :race_id, :integer, source: :raceId field :driver_id, :integer, source: :driverId belongs_to :race, Race, foreign_key: :raceId, define_field: false belongs_to :driver, Driver, foreign_key: :driverId, define_field: false end end
  36. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel THE SOLUTION

    for Custom field types Ecto.Type @behaviour Ecto.UUID
  37. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types If you need something other than… :id :binary_id :float :boolean :string :binary {:array, inner_type} :map {:map, inner_type} :decimal :date :time :naive_datetime :utc_datetime
  38. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types defmodule EncryptedField do @behaviour Ecto.Type def type, do: :binary def cast(string) when is_binary(string) do {:ok, Cipher.encrypt(string)} end def load(string) do {:ok, Cipher.decrypt(string)} end def dump(string) do {:ok, Cipher.encrypt(string)} end end
  39. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types defmodule EncryptedField do @behaviour Ecto.Type def type, do: :binary def cast(string) when is_binary(string) do {:ok, Cipher.encrypt(string)} end def load(string) do {:ok, Cipher.decrypt(string)} end def dump(string) do {:ok, Cipher.encrypt(string)} end end
  40. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types defmodule EncryptedField do @behaviour Ecto.Type def type, do: :binary def cast(string) when is_binary(string) do {:ok, Cipher.encrypt(string)} end def load(string) do {:ok, Cipher.decrypt(string)} end def dump(string) do {:ok, Cipher.encrypt(string)} end end
  41. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types defmodule EncryptedField do @behaviour Ecto.Type def type, do: :binary def cast(string) when is_binary(string) do {:ok, Cipher.encrypt(string)} end def load(string) do {:ok, Cipher.decrypt(string)} end def dump(string) do {:ok, Cipher.encrypt(string)} end end
  42. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types defmodule EncryptedField do @behaviour Ecto.Type def type, do: :binary def cast(string) when is_binary(string) do {:ok, Cipher.encrypt(string)} end def load(string) do {:ok, Cipher.decrypt(string)} end def dump(string) do {:ok, Cipher.encrypt(string)} end end
  43. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types defmodule EncryptedField do @behaviour Ecto.Type def type, do: :binary def cast(string) when is_binary(string) do {:ok, Cipher.encrypt(string)} end def load(string) do {:ok, Cipher.decrypt(string)} end def dump(string) do {:ok, Cipher.encrypt(string)} end end
  44. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types defmodule EncryptedField do @behaviour Ecto.Type def type, do: :binary def cast(string) when is_binary(string) do {:ok, Cipher.encrypt(string)} end def load(string) do {:ok, Cipher.decrypt(string)} end def dump(string) do {:ok, Cipher.encrypt(string)} end end
  45. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types defmodule F1Saver.API.Encrypt do use Ecto.Schema schema "encrypts" do field :text, EncryptedField end end
  46. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types iex> %Encrypt{text: "this is a secret message"} !|> Repo.insert() [debug] QUERY OK db=1.6ms INSERT INTO `encrypts` (`text`) VALUES (?) ["FGqTIWvjsFF3ZD%2BFBeFn0T63vulTHq%2F9NAbpJ6nEJKc%3D"] {:ok, %F1Saver.API.Encrypt{__meta__: #Ecto.Schema.Metadata!<:loaded, "encrypts!">, id: 1, text: "this is a secret message"}}
  47. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types iex> %Encrypt{text: "this is a secret message"} !|> Repo.insert() [debug] QUERY OK db=1.6ms INSERT INTO `encrypts` (`text`) VALUES (?) ["FGqTIWvjsFF3ZD%2BFBeFn0T63vulTHq%2F9NAbpJ6nEJKc%3D"] {:ok, %F1Saver.API.Encrypt{__meta__: #Ecto.Schema.Metadata!<:loaded, "encrypts!">, id: 1, text: "this is a secret message"}}
  48. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types iex> %Encrypt{text: "this is a secret message"} !|> Repo.insert() [debug] QUERY OK db=1.6ms INSERT INTO `encrypts` (`text`) VALUES (?) ["FGqTIWvjsFF3ZD%2BFBeFn0T63vulTHq%2F9NAbpJ6nEJKc%3D"] {:ok, %F1Saver.API.Encrypt{__meta__: #Ecto.Schema.Metadata!<:loaded, "encrypts!">, id: 1, text: "this is a secret message"}}
  49. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types mysql> select * from encrypts; +!!---!!-+----------------------------------------------------+ | id | text | +!!---!!-+----------------------------------------------------+ | 1 | FGqTIWvjsFF3ZD%2BFBeFn0T63vulTHq%2F9NAbpJ6nEJKc%3D | +!!---!!-+----------------------------------------------------+ 1 row in set (0.00 sec)
  50. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types iex> Repo.all(from e in Encrypt, where: e.text !== "this is a secret message") [debug] QUERY OK source="encrypts" db=0.7ms decode=3.8ms SELECT e0.`id`, e0.`text` FROM `encrypts` AS e0 WHERE (e0.`text` = 'FGqTIWvjsFF3ZD%2BFBeFn0T63vulTHq%2F9NAbpJ6nEJKc%3D') [] [%F1Saver.API.Encrypt{__meta__: #Ecto.Schema.Metadata!<:loaded, "encrypts!">, id: 1, text: "this is a secret message"}]
  51. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types iex> Repo.all(from e in Encrypt, where: e.text !== "this is a secret message") [debug] QUERY OK source="encrypts" db=0.7ms decode=3.8ms SELECT e0.`id`, e0.`text` FROM `encrypts` AS e0 WHERE (e0.`text` = 'FGqTIWvjsFF3ZD%2BFBeFn0T63vulTHq%2F9NAbpJ6nEJKc%3D') [] [%F1Saver.API.Encrypt{__meta__: #Ecto.Schema.Metadata!<:loaded, "encrypts!">, id: 1, text: "this is a secret message"}]
  52. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types iex> Repo.all(from e in Encrypt, where: e.text !== "this is a secret message") [debug] QUERY OK source="encrypts" db=0.7ms decode=3.8ms SELECT e0.`id`, e0.`text` FROM `encrypts` AS e0 WHERE (e0.`text` = 'FGqTIWvjsFF3ZD%2BFBeFn0T63vulTHq%2F9NAbpJ6nEJKc%3D') [] [%F1Saver.API.Encrypt{__meta__: #Ecto.Schema.Metadata!<:loaded, "encrypts!">, id: 1, text: "this is a secret message"}]
  53. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    Ecto.Type for Custom field types iex> Repo.all(from e in Encrypt, where: e.text !== "this is a secret message") [debug] QUERY OK source="encrypts" db=0.7ms decode=3.8ms SELECT e0.`id`, e0.`text` FROM `encrypts` AS e0 WHERE (e0.`text` = 'FGqTIWvjsFF3ZD%2BFBeFn0T63vulTHq%2F9NAbpJ6nEJKc%3D') [] [%F1Saver.API.Encrypt{__meta__: #Ecto.Schema.Metadata!<:loaded, "encrypts!">, id: 1, text: "this is a secret message"}]
  54. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @schema_prefix for Schemas defmodule F1Saver.API.Race do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :id, source: :raceId} @schema_prefix "f1" schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, foreign_key: :circuitId end end
  55. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @schema_prefix for Schemas defmodule F1Saver.API.Race do use Ecto.Schema alias F1Saver.API.Circuit @primary_key {:id, :id, source: :raceId} @schema_prefix "f1" schema "races" do field :year, :integer field :round, :integer field :name, :string field :date, :date field :url, :string belongs_to :circuit, Circuit, foreign_key: :circuitId end end
  56. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @schema_prefix for Schemas @schema_prefix "f1" iex(1)> Repo.get(Race, 1) SELECT r0.`raceId`, r0.`year`, r0.`round`, r0.`circuitId`, r0.`name`, r0.`date`, r0.`url`, r0.`circuitId` FROM `f1`.`races` AS r0 WHERE (r0.`raceId` = ?) [1]
  57. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel The Solution

    @schema_prefix for Schemas @schema_prefix “f1" iex(1)> Repo.get(Race, 1) SELECT r0.`raceId`, r0.`year`, r0.`round`, r0.`circuitId`, r0.`name`, r0.`date`, r0.`url`, r0.`circuitId` FROM `f1`.`races` AS r0 WHERE (r0.`raceId` = ?) [1]
  58. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel use Mix.Config

    config :f1_saver, F1Saver.LegacyRepo, adapter: Ecto.Adapters.MySQL, database: "f1_legacy", username: "root", password: "something_secret", hostname: "legacy.mysite.com" config :f1_saver, F1Saver.Repo, adapter: Ecto.Adapters.Postgres, database: "f1", username: "root", password: "something_secret", hostname: "new_hotness.mysite.com" config :f1_saver, ecto_repos: [F1Saver.LegacyRepo, F1Saver.Repo] Moving Forward Multiple Databases config/config.exs
  59. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel use Mix.Config

    config :f1_saver, F1Saver.LegacyRepo, adapter: Ecto.Adapters.MySQL, database: "f1_legacy", username: "root", password: "something_secret", hostname: "legacy.mysite.com" config :f1_saver, F1Saver.Repo, adapter: Ecto.Adapters.Postgres, database: "f1", username: "root", password: "something_secret", hostname: "new_hotness.mysite.com" config :f1_saver, ecto_repos: [F1Saver.LegacyRepo, F1Saver.Repo] Moving Forward Multiple Databases config/config.exs
  60. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.Application

    do use Application def start(_type, _args) do import Supervisor.Spec children = [ # Start the Ecto repository supervisor(F1Saver.Repo, []), supervisor(F1Saver.LegacyRepo, []), supervisor(F1SaverWeb.Endpoint, []), ] opts = [strategy: :one_for_one, name: F1Saver.Supervisor] Supervisor.start_link(children, opts) end def config_change(changed, _new, removed) do F1SaverWeb.Endpoint.config_change(changed, removed) :ok end end Moving Forward Multiple Databases lib/f1_saver/application.ex
  61. WORKING WITH LEGACY DATABASES IN ECTO Geoffrey Lessel defmodule F1Saver.Application

    do use Application def start(_type, _args) do import Supervisor.Spec children = [ # Start the Ecto repository supervisor(F1Saver.Repo, []), supervisor(F1Saver.LegacyRepo, []), supervisor(F1SaverWeb.Endpoint, []), ] opts = [strategy: :one_for_one, name: F1Saver.Supervisor] Supervisor.start_link(children, opts) end def config_change(changed, _new, removed) do F1SaverWeb.Endpoint.config_change(changed, removed) :ok end end Moving Forward Multiple Databases lib/f1_saver/application.ex