{"id":18303644,"url":"https://github.com/edragonconnect/ecto_tablestore","last_synced_at":"2025-06-16T06:03:18.896Z","repository":{"id":35116487,"uuid":"207128049","full_name":"edragonconnect/ecto_tablestore","owner":"edragonconnect","description":"  Alibaba Tablestore adapter for Ecto","archived":false,"fork":false,"pushed_at":"2024-06-13T14:17:23.000Z","size":361,"stargazers_count":9,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-16T06:02:38.595Z","etag":null,"topics":["ecto-adapter","tablestore"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/ecto_tablestore","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/edragonconnect.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-08T14:53:28.000Z","updated_at":"2025-03-19T16:29:27.000Z","dependencies_parsed_at":"2023-01-15T14:15:19.453Z","dependency_job_id":"661e057a-4142-4531-a3d8-ab711ffe0629","html_url":"https://github.com/edragonconnect/ecto_tablestore","commit_stats":{"total_commits":212,"total_committers":10,"mean_commits":21.2,"dds":0.1556603773584906,"last_synced_commit":"b44476e65d3205d5d60ef35227381f34c41a84f2"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/edragonconnect/ecto_tablestore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edragonconnect%2Fecto_tablestore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edragonconnect%2Fecto_tablestore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edragonconnect%2Fecto_tablestore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edragonconnect%2Fecto_tablestore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edragonconnect","download_url":"https://codeload.github.com/edragonconnect/ecto_tablestore/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edragonconnect%2Fecto_tablestore/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260109457,"owners_count":22960024,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ecto-adapter","tablestore"],"created_at":"2024-11-05T15:26:15.722Z","updated_at":"2025-06-16T06:03:18.855Z","avatar_url":"https://github.com/edragonconnect.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Alibaba Tablestore adapter for Ecto\n\n[![Module Version](https://img.shields.io/hexpm/v/ecto_tablestore.svg)](https://hex.pm/packages/ecto_tablestore)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/ecto_tablestore/)\n[![Total Download](https://img.shields.io/hexpm/dt/ecto_tablestore.svg)](https://hex.pm/packages/ecto_tablestore)\n[![License](https://img.shields.io/hexpm/l/ecto_tablestore.svg)](https://github.com/edragonconnect/ecto_tablestore/blob/master/LICENSE.md)\n[![Last Updated](https://img.shields.io/github/last-commit/edragonconnect/ecto_tablestore.svg)](https://github.com/edragonconnect/ecto_tablestore/commits/master)\n\n## Notice\n\nIf you have used this library and upgrade it into `0.11.0` or later, there are some breaking changes in `0.11.0`,\nyou may need to make a data migration before upgrade and one use case check, please see this\n[changelog](https://github.com/edragonconnect/ecto_tablestore/blob/master/CHANGELOG.md)\nfor details, if you are new to use `0.11.0` or later, please ignore this comment.\n\n## Introduce\n\nEcto 3.x adapter for [Alibaba Tablestore](https://www.alibabacloud.com/product/table-store), this\nis built on top of [`ex_aliyun_ots`](https://hex.pm/packages/ex_aliyun_ots) to implement\n`Ecto.Adapter` and `Ecto.Adapter.Schema` behaviours.\n\nSupported features:\n\n* Compatible `Ecto.Repo` API.\n\n* Support schema's `timestamps()` macro, make `inserted_at` and `updated_at` as an integer UTC\n  timestamps.\n\n* Support `:map` | `{:map, _}` | `:array` | `{:array, _}` field type, use Jason to encode the\n  field value into :string when save, use Jason to simply decode the field value into `:map` |\n  `:array` when read, the :keys option of Jason's decode always use :string.\n\n* Support the partition key is autoincrementing, use the sequence feature provided by\n  `ex_aliyun_ots`.\n\n* Automatically converts the returned original row results into corresponding schema(s).\n\n* Automatically generate the provided attribute-column field(s) of schema entity into the `filter`\n  expression option of `GetRow` (see `c:EctoTablestore.Repo.one/2`) and `BatchGet` (see\n  `c:EctoTablestore.Repo.batch_get/1`) when use `entity_full_match: true`, by default this option is\n  `false`.\n\n* Automatically generate the provided attribute-column field(s) of schema entity into the\n  `condition` expression option of `BatchWrite` (see `c:EctoTablestore.Repo.batch_write/2`) when\n  use `entity_full_match: true`, by default this option is `false`.\n\n* Automatically map changeset's attribute-column field(s) into `UpdateRow` operation when call\n  `c:EctoTablestore.Repo.update/2`:\n\n  * Use atomic increment via `{:increment, integer()}` in changeset, and return the increased\n    value in the corresponding field(s) by default;\n  * Set any attribute(s) of schema changeset as `nil` will `:delete_all` that attribute-column\n    field(s);\n  * Set existed attribute(s) in schema changeset will `:put` to save.\n\n* Support embedded schema, please refer full functions of `Ecto.Schema` for details.\n\n* Automatically use schema defined attribute fields into `:columns_to_get` in all read operations\n  by default if this option is not explicitly provided.\n\nImplement Tablestore row related functions in `EctoTablestore.Repo` module, please see\n[document](https://hexdocs.pm/ecto_tablestore/readme.html) for details:\n\n* PutRow\n* GetRow\n* UpdateRow\n* DeleteRow\n* GetRange\n* StreamRange\n* BatchGetRow\n* BatchWriteRow\n* Search\n\n## Migration\n\nProvide a simple migration to create or drop the table, the secondary index and the search index, please see\n`EctoTablestore.Migration` for details.\n\n## Usage\n\n1, Configure `My` instance(s) information of Alibaba Tablestore product.\n\n```elixir\nuse Mix.Config\n\n# config for `ex_aliyun_ots`\n\nconfig :ex_aliyun_ots, MyInstance,\n  name: \"MY_INSTANCE_NAME\",\n  endpoint: \"MY_INSTANCE_ENDPOINT\",\n  access_key_id: \"MY_OTS_ACCESS_KEY\",\n  access_key_secret: \"MY_OTS_ACCESS_KEY_SECRET\"\n\nconfig :ex_aliyun_ots,\n  instances: [MyInstance]\n\n# config for `ecto_tablestore`\n\nconfig :my_otp_app, EctoTablestore.MyRepo,\n  instance: MyInstance\n```\n\n2, Create the `EctoTablestore.MyRepo` module mentioned earlier in the configuration, use\n`EctoTablestore.Repo` and set required `otp_app` option with your OTP application's name.\n\n```elixir\ndefmodule EctoTablestore.MyRepo do\n  use EctoTablestore.Repo,\n    otp_app: :my_otp_app\nend\n```\n\n3, Each repository in Ecto defines a `start_link/0` function that needs to be invoked before using\nthe repository. In general, this function is not called directly, but used as part of your\napplication supervision tree.\n\nAdd `EctoTablestore.MyRepo` into your application start callback that defines and start your\nsupervisor. You just need to edit `start/2` function to start the repo as a supervisor on your\napplication's supervisor:\n\n```elixir\ndef start(_type, _args) do\n  children = [\n    {EctoTablestore.MyRepo, []}\n  ]\n\n  opts = [strategy: :one_for_one, name: MyApp.Supervisor]\n  Supervisor.start_link(children, opts)\nend\n```\n\n4, After finish the above preparation, we can use `MyRepo` to operate data store.\n\n## Integrate Hashids\n\nBase on unique integer of atomic-increment sequence, provides a way to simply integrate `Hashids`\nto generate your *hash* ids as the primary key when insert row(s), for `Repo.insert/2` or `Repo.batch_write/1`.\n\nAdd a dependency to your Mix project\n\n```elixir\n{:hashids, \"~\u003e 2.0\"}\n```\n\n### Use in schema\n\n```elixir\ndefmodule Module do\n  use EctoTablestore.Schema\n\n  schema \"table_name\" do\n    field(:id, Ecto.Hashids, primary_key: true, autogenerate: true,\n      hashids: [salt: \"123\", min_len: 2, alphabet: \"...\"])\n    field(:content, :string)\n  end\n\nend\n```\n\nOptions:\n\n* The `primary_key` as true is required;\n* The `autogenerate` as true is required;\n* The `salt`, `min_len` and `alphabet` of hashids options are used for configuration options from\n  `Hashids.new/1`.\n\nNotice: the `salt`, `min_len` and `alphabet` of hashids options also can be configured in the `:ecto_tablestore`\nconfig for each defined schema, for example:\n\n```elixir\nconfig :ecto_tablestore,\n  hashids: [\n    {Module, salt: \"...\", min_len: 16, alphabet: \"...\"},\n    ...\n  ]\n```\n\n### Use in migration\n\nUse `:hashids` as a type in `add` operation to define the partition key, the principle behind this\nwill use `ecto_tablestore_default_seq` as a global default table to maintain the sequences of all\ntables, if `ecto_tablestore_default_seq` is not existed, there will create this, if it is existed,\nplease ignore the \"OTSObjectAlreadyExist\" error of requested table already exists.\n\n```elixir\ndefmodule EctoTablestore.TestRepo.Migrations.TestHashids do\n  use EctoTablestore.Migration\n\n  def change do\n    create table(\"table_name\") do\n      add :id, :hashids, partition_key: true\n      add :oid, :integer\n    end\n  end\n\nend\n```\n\nOptions:\n\n* The `partition_key` option as true is required;\n* The `auto_increment` option is ignored when the partition key is `:hashids` type.\n\n## References\n\nAlibaba Tablestore product official references:\n\n* [English document](https://www.alibabacloud.com/help/doc-detail/27280.htm)\n* [中文文档](https://help.aliyun.com/document_detail/27280.html)\n\n## License\n\nThis project is licensed under the MIT license. Copyright (c) 2018- Xin Zou.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedragonconnect%2Fecto_tablestore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedragonconnect%2Fecto_tablestore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedragonconnect%2Fecto_tablestore/lists"}