【问题标题】:Create table at runtime with Ecto使用 Ecto 在运行时创建表
【发布时间】:2020-02-14 04:55:50
【问题描述】:

根据这个问题 - Dynamic Models in Phoenix Framework - 可以使用 Module.create 在 Elixir 中动态创建模型。

是否也可以在运行时为此模型在数据库中创建一个表,即不使用 Ecto 迁移文件?

【问题讨论】:

  • 只是一个简单的问题 - 表格的用途是什么?
  • 每个月我都想有一个自定义表格来存储报告的数据。但我希望系统在用户请求报告时创建此表(如果它不存在)。
  • Ecto 背后的 DB 是什么?
  • @mudasobwa MySQL

标签: elixir ecto


【解决方案1】:

用于Ecto 2.0+ 的PostgreSQLMySQL 适配器能够执行原始SQL:

qry =
  """
  CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  """

res = Ecto.Adapters.SQL.query!(Repo, qry, [])

Ecto.Adapters.SQL.query/4.

另一种(可能是首选)方式是将其委托给底层mysql shell 可执行文件:

System.cmd("mysql", ["#{create_table_script}"])

【讨论】:

  • 谢谢,我试试看!
  • Ecto 3+ 的新链接:Ecto.Adapters.SQL.query/4 该函数已从 ecto 包移至 ecto_sql 包
  • 请注意 Ecto.Adapters.SQL.query/4 在您的存储库下也可用,例如MyRepo.query/4.
【解决方案2】:

在您的情况下(每个月创建新的报告表)我会放弃创建数据库表的想法并考虑使用 ETS / DETS 组合。它们是键值存储(ETS - 内存中,DETS - 保存在磁盘上的数据 - 这是您基本上需要的),您可以阅读更多关于它们的信息 here

【讨论】:

  • 然后是审计,因为你没有保留报告的备份,你就会被解雇。这个问题如何回答“如何使用 Ecto 在 MySQL 数据库中动态创建表”?
  • 谁说过审计?如何将报告保存到 DETS 中(并在需要时将其导出为您想要的任何格式)不是备份?将数据存储在键值文件和数据库表(实际上是磁盘上的另一个文件)中是否有任何区别?动态表可能难以处理,我提供了符合 Elixir / Erlang 编程方式的优雅替代解决方案 - 这就是它回答问题的方式。
  • 没有人使用 DETS 来实现长期持久性。如果您想留在 OTP 中,请使用 mnesia 作为 kv-store。但是,即使“使用mnesia”也不能被视为“如何使用Ecto”的有效答案。
  • 没错,mnesia 是另一个有趣的解决方案,但无论如何它都是建立在 ETS/DETS 之上的。我当然可以添加代码示例,如果这将使我的答案更回答;)
  • DETS 未分发。 mnesia 不是“另一个有趣的解决方案”,mnesia 是除了 RDBMS 之外唯一的长期存储方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
  • 2014-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多