Alibaba Tablestore adapter for Ecto
Ecto 3.x adapter for Alibaba Tablestore, this is based on ex_aliyun_ots build to implement Ecto.Adapter and Ecto.Adapter.Schema behaviours.
Supported features:
- Compatible
Ecto.RepoAPI. - Support schema's
timestamps()macro, makeinserted_atandupdated_atas an integer UTC timestamps. - Support
:map|{:map, _}|:array|{:array, _}field type, use Jason to encode the field value into :string when save, use Jason to simply decode the field value into:map|:arraywhen read, the :keys option of Jason's decode always use :string. - Support the partition key is autoincrementing, use the sequence feature provided by
ex_aliyun_ots. - Automatically converts the returned original row results into corresponding schema(s).
- Automatically generate the provided attribute-column field(s) of schema entity into the
filterexpression option ofGetRow(seeEctoTablestore.Repo.one/2) andBatchGet(seeEctoTablestore.Repo.batch_get/1) useentity_full_match: true, by default this option isfalse. - Automatically generate the provided attribute-column field(s) of schema entity into the
conditionexpression option ofBatchWrite. Automatically map changeset's attribute-column field(s) into
UpdateRowoperation when callEctoTablestore.Repo.update/2:- Use atomic increment via
{:increment, integer()}in changeset, and return the increased value in the corrsponding field(s) by default; - Set any attribute(s) of schema changeset as
nilwill:delete_allthat attribute-column field(s); - Set existed attribute(s) in schema changeset will
:putto save.
- Use atomic increment via
Implement Tablestore row related functions in EctoTablestore.Repo module, please see document for details:
- PutRow
- GetRow
- UpdateRow
- DeleteRow
- GetRange
- BatchGetRow
- BatchWriteRow
- Search
Migration
Provide a simple migration to create table, please see EctoTablestore.Migration for details.
Usage
1, Configure My instance(s) information of Alibaba Tablestore product.
use Mix.Config
# config for `ex_aliyun_ots`
config :ex_aliyun_ots, MyInstance,
name: "MY_INSTANCE_NAME",
endpoint: "MY_INSTANCE_ENDPOINT",
access_key_id: "MY_OTS_ACCESS_KEY",
access_key_secret: "MY_OTS_ACCESS_KEY_SECRET"
config :ex_aliyun_ots,
instances: [MyInstance]
# config for `ecto_tablestore`
config :my_otp_app, EctoTablestore.MyRepo,
instance: MyInstance
2, Create the EctoTablestore.MyRepo module mentioned earlier in the configuration, use EctoTablestore.Repo and set required otp_app option with your OTP application's name.
defmodule EctoTablestore.MyRepo do
use EctoTablestore.Repo,
otp_app: :my_otp_app
end3, Each repository in Ecto defines a start_link/0 function that needs to be invoked before using the repository. In general, this function is not called directly, but used as
part of your application supervision tree.
Add EctoTablestore.MyRepo into your application start callback that defines and start your supervisor. You just need to edit start/2 function to start the repo as a
supervisor on your application's supervisor:
def start(_type, _args) do
children = [
{EctoTablestore.MyRepo, []}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end4, After finish the above preparation, we can use MyRepo to operate data store.
Integrate Hashids
Base on unique integer of atomic-increment sequence, provides a way to simply integrate Hashids to generate your hash ids when insert row(s), for Repo.insert/2 or Repo.batch_write/1.
use in schema
defmodule Module do
use EctoTablestore.Schema
tablestore_schema "table_name" do
field(:id, :hashids, primary_key: true, autogenerate: true,
hashids: [salt: "123", min_len: 2, alphabet: "..."])
field(:content, :string)
end
endOptions:
- The
primary_keyas true is required; - The
autogenerateas true is required; - The
salt,min_len, andalphabetof hashids option is used for configuration options fromHashids.new/1.
use in migration
Use :hashids as a type in add operation to define the partition key,
the principle behind this will use ecto_tablestore_default_seq as a global default table to maintain the sequences of all tables, if ecto_tablestore_default_seq is not existed, there will create this, if it is existed, please ignore the "OTSObjectAlreadyExist" error of requested table already exists.
defmodule EctoTablestore.TestRepo.Migrations.TestHashids do
use EctoTablestore.Migration
def change do
create table("table_name") do
add :id, :hashids, partition_key: true, auto_increment: true
add :oid, :integer
end
end
endOptions:
- The
partition_keyas true is required; - The
auto_incrementas true is required.
References
Alibaba Tablestore product official references:
License
MIT