Как выполнить запрос SQL SELECT в экто-миграции - PullRequest
0 голосов
/ 10 июля 2019

Я использую пакет Triplex для мультитенантов. Когда я создаю арендатора, он выполняет все миграции. После создания таблицы, когда я выполняю начальную миграцию, выдает ошибку:

{:error, "ERROR 42P01 (undefined_table) relation \"t2.tenants\" does not exist\n\n query: (SELECT MAX(id) from \"t2.tenants\")"}

при выборе запроса. Если я удаляю запрос выбора, другие запросы выполняются успешно.

defmodule TudoChat.Repo.Migrations.SeedTableTenants do
  use Ecto.Migration

  def up do
    execute("INSERT INTO t2.tenants (\"id\", \"inserted_at\", \"name\", \"status\", \"updated_at\") values ('1', '2019-07-08 10:37:28', 'tudo_', 'active', '2019-07-08 10:37:30')")
    execute("INSERT INTO t2.tenants (\"id\", \"inserted_at\", \"name\", \"status\", \"updated_at\") values ('2', '2019-07-08 10:38:19', 'test_', 'active', '2019-07-08 10:38:22')")
    execute("(SELECT MAX(id) from \"t2.tenants\")")
  end

  def down do
  end
end

Пожалуйста, помогите мне, как выполнить запрос выбора?

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Не используйте миграции как инструмент для заполнения вашей базы данных. Файл с семенами уже есть, если вы используете Ecto по умолчанию в priv/repo/seeds.exs. Там вам разрешено использовать экто-схемы и Repo.

Например:

  alias TudoChat.Repo
  alias TudoChat.Tenant

  Repo.insert! %Tenant{
    name: "tudo",
    status: "active"
  }

  Repo.insert! %Tenant{
    name: "test",
    status: "active"
  }

Таким образом, вам не нужно беспокоиться об идентификаторах засеянных данных и временных метках, поскольку Ecto справится с этим за вас.

После выполнения миграций вам также необходимо выполнить еще одну команду:

mix ecto.migrate
mix run priv/repo/seeds.exs

И если вам действительно нужно выполнить запрос в семенах, вам также разрешается использовать обычные экто-запросы.

0 голосов
/ 10 июля 2019

Не вводите строки с вложенными кавычками. Вам нравится избегать вложенных кавычек? Если нет, используйте ~s|...| или ~s{...} или ~s(...) или ~s<....> вместо внешних двойных кавычек. Например:

iex(2)> ~s|I said, "Go home!"|
"I said, \"Go home!\""

Вот ваше заявление с использованием ~s сигил:

execute(~s|INSERT INTO t2.tenants ("id", "inserted_at", "name", "status", "updated_at") values ('1', '2019-07-08 10:37:28', 'tudo_', 'active', '2019-07-08 10:37:30')|)

Но эта линия еще слишком длинная. Итак, сделайте что-то вроде этого:

columns = ~s|("id", "inserted_at", "name", "status", "updated_at")|
values = "('1', '2019-07-08 10:37:28', 'tudo_', 'active', '2019-07-08 10:37:30')"
query = "INSERT INTO t2.tenants #{columns} values #{values}"
IO.inspect query
execute(query)

Вот как выглядит query:

"INSERT INTO t2.tenants 
    (\"id\", \"inserted_at\", \"name\", \"status\", \"updated_at\") 
 values 
    ('1', '2019-07-08 10:37:28', 'tudo_', 'active', '2019-07-08 10:37:30')"

, пожалуйста, помогите мне, как выполнить запрос выбора?

execute("(SELECT MAX(id) from \"t2.tenants\")")

1) Требуется ли вашей базе данных круглые скобки вокруг оператора SELECT?

  |                                  |
  V                                  V
 "(SELECT MAX(id) from \"t2.tenants\")" 

2) В вашем успешном операторе INSERT вам не нужно было указывать имя таблицы. Действительно ли ваша база данных требует, чтобы вы указали имя таблицы в SELECT?

                        |           |
                        V           V
 "(SELECT MAX(id) from \"t2.tenants\")"

Как насчет:

execute("SELECT MAX(id) from t2.tenants")

Однако execute() возвращает :ok в случае успеха, поэтому я не уверен, насколько полезно выполнение этого оператора SELECT. Возможно, вы захотите взглянуть на Ecto.Adapters.SQL.query () .

...