国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Elixir Ecto: 模型的嵌入(Embed)

ningwang / 2053人閱讀

摘要:及其以上版本可以存儲類似這樣的非結(jié)構(gòu)化數(shù)據(jù)作為一個的數(shù)據(jù)封裝器提供了這些非結(jié)構(gòu)話的數(shù)據(jù)到原生數(shù)據(jù)類型的序列化和反序列化嵌入的記錄具有所有常規(guī)模型所具有的東西比如結(jié)構(gòu)化的字段生命周期回調(diào)變更集下面研究如何把結(jié)構(gòu)嵌入到模型當(dāng)中使用嵌入單個結(jié)構(gòu)可

Postgres 9.4 及其以上版本可以存儲類似 arrays, json, jsonb 這樣的非結(jié)構(gòu)化數(shù)據(jù). Ecto 作為一個 Elixir 的數(shù)據(jù)封裝器, 提供了這些非結(jié)構(gòu)話的數(shù)據(jù)到 Elixir 原生數(shù)據(jù)類型的序列化和反序列化. 嵌入的記錄具有所有常規(guī)模型所具有的東西, 比如結(jié)構(gòu)化的字段, 生命周期回調(diào), 變更集. 下面研究如何把結(jié)構(gòu)嵌入到 Ecto 模型當(dāng)中.

使用 embeds_one 嵌入單個結(jié)構(gòu)

可以使用 embeds_one 嵌入單個結(jié)構(gòu)到 Ecto 模型當(dāng)中. 嵌入的字段必須是 :map 這種非結(jié)構(gòu)化的的數(shù)據(jù)類型. 在 Postgres 中, Ecto 使用了 jsonb 作為底層數(shù)據(jù)庫字段的數(shù)據(jù)類型.

20160430043543_create_table_account.exs

defmodule EctoTest.Repo.Migrations.CreateTableAccount do
  use Ecto.Migration
  def change do
    create table(:accounts) do
      add :name, :string
      add :settings, :map  # 遷移腳本里面數(shù)據(jù)類型需要設(shè)置為 :map,
                           # 這樣 Postgrex 適配器才能正確的把它映射到 jsonb[] 數(shù)據(jù)類型
    end
  end
end

執(zhí)行項目目錄中的 ./migrate 腳本, 內(nèi)容如下

#!/bin/bash

mix ecto.migrate -r EctoTest.Repo
?  ecto_test git:(master) ? ./migrate

12:38:10.930 [info]  == Running EctoTest.Repo.Migrations.CreateTableAccount.change/0 forward

12:38:10.930 [info]  create table accounts

12:38:10.943 [info]  == Migrated in 0.0s

定義模型

defmodule EctoTest.Model.Account do
  use Ecto.Schema
  alias EctoTest.Model.Settings
  schema "accounts" do
    field :name
    embeds_one :settings, Settings
  end
end

定義嵌入到 EctoTest.Model.Account 模型中的字段:

defmodule EctoTest.Model.Settings do
  use Ecto.Model
  embedded_schema do
    field :email_signature
    field :send_emails, :boolean
  end
end

嵌入的記錄行為上和電信的關(guān)聯(lián)(associations)一樣, 只是它只能夠通過變更集(changeset)來更新和刪除

插入數(shù)據(jù)測試

# 模擬 EctoTest.get/1 返回一個 %EctoTest.Model.Account() 結(jié)構(gòu)
account = %EctoTest.Model.Account{name: "test"}

# 創(chuàng)建Settings結(jié)構(gòu)
settings = %EctoTest.Model.Settings{email_signature: "developerworks", send_emails: true}

# 創(chuàng)建變更集
changeset = Ecto.Changeset.change(account)

# 嵌入
changeset = Ecto.Changeset.put_embed(changeset, :settings, settings)

# 插入數(shù)據(jù)
changeset |> EctoTest.Repo.insert!

當(dāng)父記錄保存時, 會自動地的調(diào)用嵌入模型(Settings模型)中的 changeset/2 函數(shù).

嵌入的記錄可以通過.符號來訪問, 因此不必考慮在一般的關(guān)聯(lián)關(guān)系中的鏈接JOIN和預(yù)加載(preload)的問題:

account = Repo.get!(EctoTest.Model.Account, 1)
account.settings #=> %Settings{...}
使用 embeds_many 嵌入多個結(jié)構(gòu)

embeds_many 允許你嵌入一個 Ecto 結(jié)構(gòu)數(shù)組到一個關(guān)系數(shù)據(jù)庫字段中. 在數(shù)據(jù)庫底層 Postgres 使用了 arrayjsonb 數(shù)據(jù)類型來實現(xiàn) embeds_many.

defmodule EctoTest.Repo.Migrations.CreateTablePeople do
  use Ecto.Migration

  def up do
    create table(:people) do
      add :name, :string
      add :address, {:array, :map}, default: []
    end
  end

  def down do
    drop table(:people)
  end
end

定義 Person, Address 模型:

defmodule EctoTest.Model.Person do
  use Ecto.Schema
  alias EctoTest.Model.Address

  schema "people" do
    field :name
    embeds_many :addresses, Address
  end

  def test_insert do
    changeset = Ecto.Changeset.change(%__MODULE__{})
    addresses = [
      %Address{street_name: "20 Foobar Street",city: "Boston",state: "MA",zip_code: "02111"},
      %Address{street_name: "1 Finite Loop", city: "Cupertino",state: "CA",zip_code: "95014"}
    ]
    changeset = Ecto.Changeset.put_embed(changeset, :addresses, addresses)
    Repo.insert!(changeset)
  end
end


defmodule EctoTest.Model.Address do
  use Ecto.Schema

  embedded_schema do
    field :street_name
    field :city
    field :state
    field :zip_code
  end
end

設(shè)置多對多字段的值

iex(1)> EctoTest.Model.Person.test_insert

13:44:25.731 [debug] QUERY OK db=9.4ms
INSERT INTO "people" ("addresses") VALUES ($1) RETURNING "id" [[%{city: "Boston", id: "2de7fd44-a1cf-44cd-a060-d6260325ac90", state: "MA", street_name: "20 Foobar Street", zip_code: "02111"}, %{city: "Cupertino", id: "bb65fd96-f1b1-4f0d-a92e-712884e40a7c", state: "CA", street_name: "1 Finite Loop", zip_code: "95014"}]]
%EctoTest.Model.Person{__meta__: #Ecto.Schema.Metadata<:loaded>,
 addresses: [%EctoTest.Model.Address{city: "Boston", id: "2de7fd44-a1cf-44cd-a060-d6260325ac90", state: "MA",
   street_name: "20 Foobar Street", zip_code: "02111"},
  %EctoTest.Model.Address{city: "Cupertino", id: "bb65fd96-f1b1-4f0d-a92e-712884e40a7c", state: "CA",
   street_name: "1 Finite Loop", zip_code: "95014"}], id: 1, name: nil}

has_many 一樣訪問:

iex(2)> person = EctoTest.Repo.get!(EctoTest.Model.Person, 1)

13:45:04.634 [debug] QUERY OK db=1.4ms decode=9.5ms
SELECT p0."id", p0."name", p0."addresses" FROM "people" AS p0 WHERE (p0."id" = $1) [1]
%EctoTest.Model.Person{__meta__: #Ecto.Schema.Metadata<:loaded>,
 addresses: [%EctoTest.Model.Address{city: "Boston", id: "2de7fd44-a1cf-44cd-a060-d6260325ac90", state: "MA",
   street_name: "20 Foobar Street", zip_code: "02111"},
  %EctoTest.Model.Address{city: "Cupertino", id: "bb65fd96-f1b1-4f0d-a92e-712884e40a7c", state: "CA",
   street_name: "1 Finite Loop", zip_code: "95014"}], id: 1, name: nil}

iex(3)> person.addresses
[%EctoTest.Model.Address{city: "Boston", id: "2de7fd44-a1cf-44cd-a060-d6260325ac90", state: "MA",
  street_name: "20 Foobar Street", zip_code: "02111"},
 %EctoTest.Model.Address{city: "Cupertino", id: "bb65fd96-f1b1-4f0d-a92e-712884e40a7c", state: "CA",
  street_name: "1 Finite Loop", zip_code: "95014"}]
權(quán)衡

記錄的嵌入是 Ecto 提供的多個強大的能之一. 很容易給嵌入的記錄添加字段, 不需要運行時修改數(shù)據(jù)庫結(jié)構(gòu). 這些都是優(yōu)勢, 但有的場景下也會帶來一些問題, 因此需要權(quán)衡是否應(yīng)該使用嵌入.

使用非結(jié)構(gòu)化數(shù)據(jù), 丟失了SQL數(shù)據(jù)庫提供的關(guān)系特性, 例如, 一個記錄只能嵌入到一個父表中, 因此不能使用嵌入建模多對多關(guān)系, 也不能使用數(shù)據(jù)庫約束, 雖然可以在應(yīng)用程序中檢查數(shù)據(jù)的完整性, 但是更好的方式是在數(shù)據(jù)庫級別進行驗證, 以保障數(shù)據(jù)的完整性.

示例代碼

https://github.com/developerworks/ecto_test

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/38940.html

相關(guān)文章

  • Elixir Ecto: PostgreSQL大自增長主鍵設(shè)置

    摘要:要解決的問題數(shù)據(jù)庫中存儲的行數(shù)超過了類型所能容納的數(shù)量因此需要采用類型的整數(shù)作為主鍵的取值范圍為到的取值范圍為到完整的字段的數(shù)據(jù)類型可以參考這里遷移腳本要點的參數(shù)要設(shè)置為通過宏指定主鍵列類型為模型的聲明要點主鍵要聲明為類型完 要解決的問題 數(shù)據(jù)庫中存儲的行數(shù)超過了 serial 類型所能容納的數(shù)量, 因此需要采用 bigserial 類型的整數(shù)作為主鍵serial 的取值范圍為: 1...

    yvonne 評論0 收藏0
  • Elixir Ecto: 使用Geo庫操作空間數(shù)據(jù)(地理坐標)

    摘要:簡介數(shù)據(jù)格式空間數(shù)據(jù)的文本標識空間數(shù)據(jù)的二進制標識基于對象表示法的地理空間信息數(shù)據(jù)交換格式的庫提供了上述三種格式的相互轉(zhuǎn)換函數(shù)配置添加依賴配置擴展創(chuàng)建刪除擴展的移植腳本腳本內(nèi)容執(zhí)行移植插入數(shù)據(jù)軌跡點粵獲取經(jīng)緯度粵查詢聯(lián)系如何查詢字段例 簡介 數(shù)據(jù)格式 Abbr Fullname Description WKT Well Known Text 空間數(shù)據(jù)的文本標識 WKB ...

    Blackjun 評論0 收藏0
  • Elixir Ecto: 在Postgresql中插入二進制數(shù)據(jù)

    摘要:本文以用一個在數(shù)據(jù)庫中保存圖片信息為例展示如何向中插入二進制數(shù)據(jù)首先我們要知道中唯一一種二進制數(shù)據(jù)的類型為表示字節(jié)數(shù)組或字節(jié)序列對應(yīng)于和中的下面是一個示例遷移腳本這里也可以為實際上在執(zhí)行數(shù)據(jù)庫中字段的類型就是當(dāng)然除了圖片文件以外你還 本文以用一個在數(shù)據(jù)庫中保存圖片信息為例, 展示如何向 Postgresql 中插入二進制數(shù)據(jù). showImg(https://segmentfault....

    CarterLi 評論0 收藏0
  • Elixir Ecto: 在Postgres中使用UUID類型主鍵

    摘要:使用作為主鍵的目的降低類型這種自增線性特征作為隨機生成的字符串讓更離散增強系統(tǒng)的反爬蟲能力至少避免通過的線性增加來爬取內(nèi)容這種最簡單的爬取方式使用主鍵的是那種方式各有優(yōu)缺點可按實際需求自行權(quán)衡在應(yīng)用程序中生成并插入到數(shù)據(jù)庫通過使用擴展自動生 使用UUID作為主鍵的目的 降低Serial類型這種自增ID線性特征, UUID作為隨機生成的字符串, 讓ID更離散, 增強系統(tǒng)的反爬蟲能力(至...

    OnlyLing 評論0 收藏0
  • 前端速查表大全,分享一些技術(shù)和工具簡明教程

    摘要:這個速查表主要是分享互聯(lián)網(wǎng)上一些比較常用的工具和技術(shù)常用內(nèi)容,如編輯器的快捷鍵的命令行的選擇器的屬性等,這個列表簡單收集了常用的工具,可以收藏用于平時的備忘錄,需要用到的時候可以及時查閱。 這個速查表主要是分享互聯(lián)網(wǎng)上一些比較常用的工具和技術(shù)常用內(nèi)容,如編輯器的快捷鍵、git的命令行、jQuery的API選擇器、CSS的flexbox屬性等,這個列表簡單收集了常用的工具,可以收藏用于平...

    xiaochao 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<