insert_all与类型:utc_datetime不匹配

时间:2018-12-11 03:44:46

标签: elixir phoenix-framework ecto

所以我有一个对象数组,我想使用"\\s+"保存。我收到一个错误,指出我的一个字段不匹配。

edtr.json

insert_all

post_controller

{
"edtrs":
[
    {
        "dtr_date": "2018-12-29T16:00:00.000Z",
        "user_id": "8189f04b-e3d7-4d17-8df2-fedbeb0399b1"
    },
    {
        "dtr_date": "2018-12-30T16:00:00.000Z",
        "user_id": "8189f04b-e3d7-4d17-8df2-fedbeb0399b1"
    }
]}

错误

   def create_edtr(edtrs) do maps = Enum.map(edtrs["edtrs"], fn(item) -> %{dtr_date: item["dtr_date"], user_id: item["user_id"]} end) IO.inspect maps, label: "MAPS" Repo.insert_all(Edtr,maps) end 中的

HrisApp.Attendance.Edtr.dtr_date与类型insert_all不匹配

2 个答案:

答案 0 :(得分:1)

您的firrtl.passes.CheckGenders$WrongGender: @[Platform.scala 283:19:Config.fir@540640.4]: [module Platform] Expression sys.hart_clocks is used as a FEMALE but can only be used as a MALE. firrtl.passes.CheckGenders$WrongGender: @[Platform.scala 284:19:Config.fir@540641.4]: [module Platform] Expression sys.hart_resets is used as a FEMALE but can only be used as a MALE. 字段有一个字符串,但是在数据库表的架构中,您必须指定dtr_date字段为dtr_date类型,因此ecto要求您向其传递:utc_datetime结构。

DateTime

查看此处:

Phoenix/Ecto - converting ISO string into utc_datetime primitive type


请注意,如果您使用ecto变更集,那么iex(1)> date_string = "2018-12-30T16:00:00.000Z" "2018-12-30T16:00:00.000Z" iex(2)> {:ok, dt_struct, utc_offset} = DateTime.from_iso8601(date_string) {:ok, #DateTime<2018-12-30 16:00:00.000Z>, 0} iex(3)> dt_struct #DateTime<2018-12-30 16:00:00.000Z> 会将数据转换为适合您的类型。这是一个示例:

目录结构:

cast()

edtr.ex:

lib/
    myapp/
         edtr_api/
                 edtr.ex
                 edtr_api.ex
    myapp_web/

edtr_api.ex

defmodule Myapp.EdtrApi.Edtr do

  use Ecto.Schema
  import Ecto.Changeset
  alias Myapp.EdtrApi.Edtr

  schema "edtrs" do
    field :dtr_date, :utc_datetime, null: false
    field :user_id, :string

    timestamps()
  end

  def create_changesets(edtr_data) do
    Enum.map(edtr_data, fn data ->
      %Edtr{}
      |> cast(data, [:dtr_date, :user_id])
      |> validate_required([:dtr_date, :user_id])
      |> validate_length(:user_id, min: 10, max: 100)
    end)
  end

end

然后您需要创建一个迁移文件:

defmodule Myapp.EdtrApi do
  alias Myapp.EdtrApi.Edtr
  alias Myapp.Repo

  def get_data() do 
    [
      %{
          "dtr_date" => "2018-12-29T16:00:00.000Z",
          "user_id" => "8189f04b-e3d7-4d17-8df2-fedbeb0399b1"
      },
      %{
          "dtr_date" => "2018-12-30T16:00:00.000Z",
      },
    ]
  end

  def insert_edtrs() do
    changesets = Edtr.create_changesets(get_data())
    Enum.map(changesets, fn changeset -> Repo.insert(changeset) end) 
  end

  def all() do
    Repo.all(Edtr)
  end

end

然后更改迁移文件以模仿您的Edtr模式:

myapp / priv / repo / migrations / 20181211070748_create_edtrs.exs

~/phoenix_apps/myapp$ mix ecto.gen.migration create_edtrs

然后执行迁移以在数据库中创建表:

defmodule Myapp.Repo.Migrations.CreateEdtrs do
  use Ecto.Migration

  def change do
    create table(:edtrs) do
      add :dtr_date, :utc_datetime, null: false
      add :user_id, :string

      timestamps()
    end

  end
end

现在在iex中试用:

 ~/phoenix_apps/myapp$ mix ecto.migrate

在输出中,您可以看到在返回的$ iex -S mix Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> alias Myapp.EdtrApi Myapp.EdtrApi iex(2)> alias Myapp.EdtrApi.Edtr Myapp.EdtrApi.Edtr iex(3)> Myapp.Repo.delete_all(Edtr) [debug] QUERY OK source="edtrs" db=1.0ms decode=1.7ms queue=0.9ms DELETE FROM "edtrs" AS e0 [] {0, nil} iex(4)> EdtrApi.insert_edtrs() [debug] QUERY OK db=7.4ms queue=2.1ms INSERT INTO "edtrs" ("dtr_date","user_id","inserted_at","updated_at") VALUES ($1,$2,$3,$4) RETURNING "id" [#DateTime<2018-12-29 16:00:00Z>, "8189f04b-e3d7-4d17-8df2-fedbeb0399b1", ~N[2018-12-11 09:11:18], ~N[2018-12-11 09:11:18]] [debug] QUERY OK db=2.3ms queue=1.0ms INSERT INTO "edtrs" ("dtr_date","user_id","inserted_at","updated_at") VALUES ($1,$2,$3,$4) RETURNING "id" [#DateTime<2018-12-30 16:00:00Z>, "8189f04b-e3d7-4d17-8df2-fedbeb0399b1", ~N[2018-12-11 09:11:18], ~N[2018-12-11 09:11:18]] [ ok: %Myapp.EdtrApi.Edtr{ __meta__: #Ecto.Schema.Metadata<:loaded, "edtrs">, dtr_date: #DateTime<2018-12-29 16:00:00Z>, id: 1, inserted_at: ~N[2018-12-11 09:11:18], updated_at: ~N[2018-12-11 09:11:18], user_id: "8189f04b-e3d7-4d17-8df2-fedbeb0399b1" }, ok: %Myapp.EdtrApi.Edtr{ __meta__: #Ecto.Schema.Metadata<:loaded, "edtrs">, dtr_date: #DateTime<2018-12-30 16:00:00Z>, id: 2, inserted_at: ~N[2018-12-11 09:11:18], updated_at: ~N[2018-12-11 09:11:18], user_id: "8189f04b-e3d7-4d17-8df2-fedbeb0399b1" } ] iex(5)> 内,日期字符串已转换为DateTime结构。叫Edtr structs就是这样做的。

好的,现在让我们从数据中删除cast()

user_id

然后重试:

  def get_edtrs() do 
    [
      %{
          "dtr_date" => "2018-12-29T16:00:00.000Z",
          "user_id" => "8189f04b-e3d7-4d17-8df2-fedbeb0399b1"
      },
      %{
          "dtr_date" => "2018-12-30T16:00:00.000Z",
      },
    ]
  end

如果您检查输出的最后一部分,请注意:

1)第二个插入返回一个Changeset结构,而不是像第一个插入那样返回Edtr结构。

2)第二个insert()返回~/phoenix_apps/myapp$ iex -S mix Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] Compiling 1 file (.ex) Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> alias Myapp.EdtrApi.Edtr Myapp.EdtrApi.Edtr iex(2)> EdtrApi.insert_edtrs() [debug] QUERY OK db=4.4ms decode=2.9ms queue=1.5ms INSERT INTO "edtrs" ("dtr_date","user_id","inserted_at","updated_at") VALUES ($1,$2,$3,$4) RETURNING "id" [#DateTime<2018-12-29 16:00:00Z>, "8189f04b-e3d7-4d17-8df2-fedbeb0399b1", ~N[2018-12-11 09:12:17], ~N[2018-12-11 09:12:17]] [ ok: %Myapp.EdtrApi.Edtr{ __meta__: #Ecto.Schema.Metadata<:loaded, "edtrs">, dtr_date: #DateTime<2018-12-29 16:00:00Z>, id: 3, inserted_at: ~N[2018-12-11 09:12:17], updated_at: ~N[2018-12-11 09:12:17], user_id: "8189f04b-e3d7-4d17-8df2-fedbeb0399b1" }, error: #Ecto.Changeset< action: :insert, changes: %{dtr_date: #DateTime<2018-12-30 16:00:00Z>}, errors: [user_id: {"can't be blank", [validation: :required]}], data: #Myapp.EdtrApi.Edtr<>, valid?: false > ] iex(3)> 而不是error: ...,并且Changeset包含:

ok: ...

然后,如果您列出数据库表中的所有内容:

errors: [user_id: {"can't be blank", [validation: :required]}],

...您会看到带有错误的变更集没有在数据库中插入任何内容,因为只有三个条目。

答案 1 :(得分:1)

FWIW,我将其放在这里。几天前,我遇到了类似的问题,但原因不同。这个答案可能与所陈述的确切问题无关,但是我一直很难在互联网上寻找答案,所以就在这里。

至少对于使用import cv2 import numpy as np arr = np.random.uniform(size=(3,256,256))*255 # It's a r,g,b array img = cv2.merge((arr[2], arr[1], arr[0])) # Use opencv to merge as b,g,r cv2.imwrite('out.png', img) 驱动程序的MySQL,此错误可能是由MariaEx结构中的非零微秒 引起的。 AFAIU,前者不允许。是否要将DateTime的实例存储到DateTime(例如MySQL)中,将无法立即使用,显示如上的消息。

要解决此问题,请使用DateTime.truncate/2DateTime.utc_now()作为第二个参数:

:seconds