Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 为主键和验证生成自定义编号_Elixir_Ecto - Fatal编程技术网

Elixir 为主键和验证生成自定义编号

Elixir 为主键和验证生成自定义编号,elixir,ecto,Elixir,Ecto,我有以下模式: @primary_key false schema "companies" do field :number, :integer, primary_key: true field :name, :string field :street, :string field :zipcode, :integer field :location, :string

我有以下模式:

  @primary_key false
  schema "companies" do
    field :number,         :integer, primary_key: true
    field :name,           :string
    field :street,         :string
    field :zipcode,        :integer
    field :location,       :string
    field :phone,          :integer
    field :company_class,  :string
    field :country_iso,    :string
    field :email,          :string
    field :password,       :string, virtual: true
    field :password_hash,  :string
    has_many :contacts,    Busiket.Contact, on_delete: :delete_all

    timestamps
  end

  def register(struct, params \\ %{}) do

  end
当通过寄存器功能创建变更集时,如何为字段
编号
生成编号


如果数字已经可用或不可用,我如何首先验证数据库以避免重复。

这里有一种方法可以创建一个从1000000开始的列,并自动分配一个与前一个值+1大致相等的唯一值(大概是因为id可能被“跳过”)因为失败的事务和可能的其他情况)

此答案特定于PostgreSQL,因为它使用PostgreSQL特定的
setval
pg_get_serial_sequence
函数

迁移:

defmodule MyApp.Repo.Migrations.CreateCompany do
  use Ecto.Migration

  def up do
    create table(:companies, primary_key: false) do
      add :number, :serial, primary_key: true
      timestamps()
    end
    execute "select setval(pg_get_serial_sequence('companies', 'number'), 999999)"
  end

  def down do
    drop table(:companies)
  end
end
型号:

defmodule MyApp.Company do
  use MyApp.Web, :model

  @primary_key false
  schema "companies" do
    field :number, :integer, primary_key: true, read_after_writes: true

    timestamps()
  end
end
演示:

iex(1)>Repo.insert!%{}公司
[调试]查询OK db=2.7ms队列=0.1ms
在“公司”中插入(“插入的”、“更新的”)值($1,$2),返回“数字”[{{2016,12,5}、{15,57,44,0}、{2016,12,5}、{15,57,44,0}]
%MyApp.Company{{uuuuuu meta}:{35; exto.Schema.Metadata,
插入地址:EXTO.DateTime,编号:1000000,
更新地址:#exto.DateTime}
iex(2)>回购插入%{}公司
[调试]查询OK db=4.5ms
在“公司”中插入(“插入的”、“更新的”)值($1,$2),返回“数字”[{{2016,12,5}、{15,57,44,0}、{2016,12,5}、{15,57,44,0}]
%MyApp.Company{{uuuuuu meta}:{35; exto.Schema.Metadata,
插入地址:EXTO.DateTime,编号:1000001,
更新地址:#exto.DateTime}
iex(3)>回购插入%{}公司
[调试]查询OK db=3.4ms队列=0.1ms
在“公司”中插入值($1,$2),返回“数字”[{{2016,12,5}、{15,57,45,0}、{2016,12,5}、{15,57,45,0}]
%MyApp.Company{{uuuuuu meta}:{35; exto.Schema.Metadata,
插入地址:EXTO.DateTime,编号:1000002,
更新地址:#exto.DateTime}
一些注意事项:

  • 我将序列值设置为
    999999
    ,以确保序列中的下一个数字是
    1000000

  • 我在列中添加了
    read\u-after\u-writes:true
    ,因为该字段的值是由数据库生成的,如果
    read\u-after\u-writes
    设置为
    true
    ,则该字段在插入后不会重新加载,并将保持为
    nil


这里有一种方法可以创建一个从1000000开始的列,并自动分配一个唯一的值,该值大致相当于前一个值+1(大致是因为一个id可能会因为失败的事务和其他一些情况而被“跳过”)

此答案特定于PostgreSQL,因为它使用PostgreSQL特定的
setval
pg_get_serial_sequence
函数

迁移:

defmodule MyApp.Repo.Migrations.CreateCompany do
  use Ecto.Migration

  def up do
    create table(:companies, primary_key: false) do
      add :number, :serial, primary_key: true
      timestamps()
    end
    execute "select setval(pg_get_serial_sequence('companies', 'number'), 999999)"
  end

  def down do
    drop table(:companies)
  end
end
型号:

defmodule MyApp.Company do
  use MyApp.Web, :model

  @primary_key false
  schema "companies" do
    field :number, :integer, primary_key: true, read_after_writes: true

    timestamps()
  end
end
演示:

iex(1)>Repo.insert!%{}公司
[调试]查询OK db=2.7ms队列=0.1ms
在“公司”中插入(“插入的”、“更新的”)值($1,$2),返回“数字”[{{2016,12,5}、{15,57,44,0}、{2016,12,5}、{15,57,44,0}]
%MyApp.Company{{uuuuuu meta}:{35; exto.Schema.Metadata,
插入地址:EXTO.DateTime,编号:1000000,
更新地址:#exto.DateTime}
iex(2)>回购插入%{}公司
[调试]查询OK db=4.5ms
在“公司”中插入(“插入的”、“更新的”)值($1,$2),返回“数字”[{{2016,12,5}、{15,57,44,0}、{2016,12,5}、{15,57,44,0}]
%MyApp.Company{{uuuuuu meta}:{35; exto.Schema.Metadata,
插入地址:EXTO.DateTime,编号:1000001,
更新地址:#exto.DateTime}
iex(3)>回购插入%{}公司
[调试]查询OK db=3.4ms队列=0.1ms
在“公司”中插入值($1,$2),返回“数字”[{{2016,12,5}、{15,57,45,0}、{2016,12,5}、{15,57,45,0}]
%MyApp.Company{{uuuuuu meta}:{35; exto.Schema.Metadata,
插入地址:EXTO.DateTime,编号:1000002,
更新地址:#exto.DateTime}
一些注意事项:

  • 我将序列值设置为
    999999
    ,以确保序列中的下一个数字是
    1000000

  • 我在列中添加了
    read\u-after\u-writes:true
    ,因为该字段的值是由数据库生成的,如果
    read\u-after\u-writes
    设置为
    true
    ,则该字段在插入后不会重新加载,并将保持为
    nil


您不使用自动递增键的原因是什么?是的,因为我想使用数字作为id。这不是一个好做法吗?那么“生成数字”是什么意思?具有自动递增功能的整数键将创建值为0、1、2……的记录。我将生成一个数字,该数字将始终包含7个数字,例如:
1000554
或'4117455'。该数字将作为客户编号@Dogbert这是一个很好的做法?你为什么不使用自动递增键?是的,因为我想使用数字作为id。这不是一个好做法吗?那么“生成数字”是什么意思?具有自动递增功能的整数键将创建值为0、1、2……的记录。我将生成一个数字,该数字将始终包含7个数字,例如:
1000554
或'4117455'。该数字将作为客户编号@多伯特:这是一个很好的练习?非常感谢你的帮助。你是长生不老药队的吗?我还有一个问题,请看以下内容并注意
countries\u code
表,使用iso作为主键而不是默认的
id
不是更好的选择。稍后,
countries
表将使用
countries\u代码
进行约束。非常感谢您的帮助。你是长生不老药队的吗?我还有一个问题,请看以下内容并注意
countries\u code
表,使用iso作为主键而不是默认的
id
不是更好的选择。稍后,
countries
表将使用
countries\u代码
进行约束。