【问题标题】:Best way to init database with specific data by environment (dev, pprod, prod) using Mongock使用 Mongock 按环境(dev、pprod、prod)使用特定数据初始化数据库的最佳方法
【发布时间】:2021-09-14 13:47:13
【问题描述】:

我正在使用 Mongock 来初始化一个带有一些配置的 MongoDb 数据库,通过调用系统授权用户数组。 {systemId: 'a', authorizedUsers: ['user1', user2]}.

我的问题来自这样一个事实,即在 dev 中 user1 和 user2 被授权,但在 prod 中只有 user1 被授权。

  • 添加一个env属性{env: 'dev', systemId: 'a', authorizedUsers: ['user1', user2]}并在我们搜索授权用户时将其用作过滤器会更好吗?缺点是 DB 中有不同的配置可用,我们需要选择正确的配置。
  • 或者在 Mongock 初始化函数(ChangeSet)中读取运行 Mongock 的环境并初始化正确的数据是否更好?缺点是我们无法在正确的环境中测试 init 的正确性
  • 更好的解决方案?

提前感谢您的回复

编辑以阐明这两个选项

  • 选项 1

    @ChangeLog
    public class UsersChangeLogs {
    
     @ChangeSet(...)
     public void addUsers() {
     //add dev users {env: 'dev', systemId: 'a', authorizedUsers: ['user1', 'user2']}
     //add prod users {env: 'prod', systemId: 'a', authorizedUsers: ['user1', 'user2']}
     }
    
    }


    @Service
    class AuthorizedUsers {
     @Value("env")
     private String env;
     List<User> getAuthorizedUsers() {
      return db.users.filter(env)
    }
    }

  • 选项 2:(由@Mongock 团队提出)(已选择)

    @ChangeLog
    public class UsersChangeLogs {
    
     @Profile("dev")
     @ChangeSet(...)
     public void addUsers() {
     //add dev users {systemId: 'a', authorizedUsers: ['user1', 'user2']}
     }
    
     @Profile("prod")
     @ChangeSet(...)
     public void addUsers() {
     //add prod users {systemId: 'a', authorizedUsers: ['user1', 'user2']}
     }
    
    }

【问题讨论】:

    标签: database mongodb environment-variables initialization mongock


    【解决方案1】:

    如果我没记错的话,我在这个问题中看到了两个部分

    1. 存储用户配置的位置/如何将其传递给 Mongock
    2. 根据该配置,初始化您的 MongoDB 数据库。

    我想我们都同意第二步很明确:Mongock 以某种方式获取配置并执行迁移。

    关于如何向 Mongock 提供该配置,在您提到的第一个选项中,您提到为环境添加一个字段,对吗?您是说生产环境和开发环境使用相同的数据库吗?在我看来,除非你有一个非常好的理由,否则我不会推荐。在我的理想世界中,每个环境都有一个数据库,因此不需要环境字段。 Mongock 只需要从之前添加的集合中获取信息。

    那么问题是如何将有关用户的配置数据添加到数据库中。如果它可以从您的 java 代码中硬编码,您可以在 Mongock 中轻松完成。如果您使用的是 Spring,您可以使用 @Profile 来计算哪个 changeLog 在哪个环境中执行。

    如果不是,另一个想法是将这些用户作为环境变量或配置传递。如果您使用的是 kubernetes,这种工具的 ansible,通过环境变量提供它不是一个坏主意。但我想我没有足够的信息来对任何选项做出更多承诺。

    @Profile("dev")
    @ChangeLog
    public class DevUsersChangeLogs {
    
     @ChangeSet(...)
     public void addUsers() {
     //add users {systemId: 'a', authorizedUsers: ['user1', 'user2']}
     }
    
    }
    
    @Profile("prod")
    @ChangeLog
    public class ProdUsersChangeLogs {
    
     @ChangeSet(...)
     public void addUsers() {
     //add users {systemId: 'a', authorizedUsers: ['user1']}
     }
    
    }
    

    然后您可以根据您的用户执行迁移

    @ChangeLog
    public class ProperMigration {
    
     @ChangeSet(...)
     public void changeSetMethod() {
     //migration code
     }
    
    
    }
    

    【讨论】:

    • 感谢您的回复。是的,我们可以说主要问题是第 2 部分。我并不是说我们为 dev 和 prod 拥有相同的数据库。我在第一个选项中要说的是,我将在每个数据库中保存 4 个配置,并且为了知道(在我的应用程序中)使用哪个配置,我将添加 env 字段。我在文档中找到了@Profile,这就是我在代码中使用的。正如你所说,我认为这是做我想做的最优雅的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 2019-07-31
    • 2021-08-28
    • 2021-01-08
    相关资源
    最近更新 更多