You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Amnesia创建的数据库在Phoenix应用及observer中无法查看的原因

排查 Amnesia 数据在 Phoenix 应用中不可见的问题

我刚踩过Amnesia和Phoenix整合的坑,咱们一步步来排查你遇到的问题:

1. 数据库存储路径不统一

Amnesia 默认会把磁盘数据库放在当前运行进程的工作目录下的 Mnesia 文件夹里。哪怕你觉得都是在项目根目录运行,也可能因为启动方式的细微差异(比如 IDE 启动 vs 终端启动)导致路径偏差;或者你的 database.ex 里没明确指定统一路径,最终 mix 任务和 Phoenix 读写的是完全不同的数据库文件。

解决方法:

  • 在 database.ex 定义数据库时,明确指定存储路径(推荐放在项目的 priv 目录下,避免版本控制系统误提交):
    defdatabase Database do
      # 保留你原有的 deftable 定义
      dir "./priv/mnesia"
    end
    
  • 在全局配置文件 config/config.exs 里统一设置 Mnesia 目录,确保所有进程都用同一个路径:
    config :mnesia, dir: "./priv/mnesia"
    

2. Phoenix 应用未正确初始化数据库表

你的 mix 任务里肯定手动执行了 Amnesia.start() 和 Database.create!() 来加载表,但 Phoenix 启动时并不会自动帮你做这件事。如果应用启动时没加载数据库表,自然看不到之前插入的数据。

解决方法:

  • 修改 lib/my_app/application.ex 的 start/2 函数,把数据库初始化逻辑放在最前面:
    def start(_type, _args) do
      # 先启动 Amnesia 并加载数据库
      Amnesia.start()
      # 确保磁盘数据库和表存在,wait() 会阻塞直到表加载完成
      Database.create!(disk: true)
      Database.wait()
    
      # 保留你原有的子树启动代码
      children = [
        MyApp.Repo,
        MyAppWeb.Endpoint
        # 其他服务...
      ]
    
      Supervisor.start_link(children, strategy: :one_for_one)
    end
    

3. 数据操作未在事务中执行

Amnesia 的磁盘存储依赖事务来持久化数据。如果你的 mix 任务里插入数据时没包裹在 Amnesia.transaction 块中,IO.inspect 能读到的只是内存中的临时数据,根本没写入磁盘。

解决方法:

  • 检查你的 Mix.Tasks.PopulateDB 代码,确保所有数据写入操作都在事务块里:
    def run(_args) do
      Amnesia.start()
      Database.create!(disk: true)
      Database.wait()
    
      Amnesia.transaction do
        # 你的数据填充逻辑,比如:
        Enum.each(1..10, fn id ->
          MyApp.Database.User.write(%MyApp.Database.User{id: id, name: "User #{id}"})
        end)
      end
    
      IO.puts("测试数据填充完成")
    end
    

4. 运行环境不一致

如果你的 mix 任务默认运行在 :dev 环境,但 Phoenix 启动时不小心切换到了其他环境(比如 :prod),而不同环境的 Mnesia 配置不同,也会导致两边读写不同的数据库。

解决方法:

  • 运行 mix 任务时明确指定环境,和 Phoenix 保持一致:
    MIX_ENV=dev mix PopulateDB
    
  • 检查 config/dev.exs、config/prod.exs 等配置文件,确保各个环境下的 Mnesia 目录配置统一(如果需要区分环境,也要保证任务和应用用的是同一个环境)。

按照上面的步骤调整后,你可以先重新运行 mix PopulateDB,然后去 ./priv/mnesia 目录下确认生成了数据库文件,再启动 Phoenix 应用,此时不管是查询数据还是用 observer:start() 查看,都应该能看到你的表和数据了。

内容的提问来源于stack exchange,提问作者Jas6033

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:39:12