Python 多环境配置管理

2020-02-24

一、概述

实际工程开发中常常会对开发、测试和生产等不同环境配置不同的数据库环境,传统方式可以通过添加不同环境的配置文件达到部署时的动态切换的效果。这种方式还不错,不过不同环境间往往会共享相同的配置而造成一些重复工作。

项目代码

  1. ./
  2. ├── conf.py
  3. └── test.py

别看只有2个文件,实际情况是有十几个文件,这里只是举例而已!

conf.py 这个是配置文件,其他py文件都依赖于它

  1. #!/usr/bin/env python3
  2. # coding: utf-8
  3. # 配置文件
  4. # k8s信息#########################################
  5. # 开发环境####################
  6. K8S_MASTER = "192.168.0.162"
  7. K8S_USERNAME = "root"
  8. K8S_PASSWD = "root"
  9. # # 生产环境####################
  10. # K8S_MASTER = "10.0.0.167"
  11. # K8S_USERNAME = "root"
  12. # K8S_PASSWD = "abcd@1234"

test.py 测试文件,下面的代码时伪代码,仅供演示!

  1. #!/usr/bin/env python3
  2. # coding: utf-8
  3. import conf
  4. def ssh2(ip,username,password,cmd): # 远程执行命令
  5. print(ip,username,password,cmd)
  6. return True
  7. res = ssh2(conf.K8S_MASTER,conf.K8S_USERNAME,conf.K8S_PASSWD,"uptime")
  8. print(res)

需求

目前情况是,执行test.py,是这样的

  1. python3 test.py

如果需要切换环境,要修改conf.py,将对应的变量注释掉即可!

但是如果变量过多,注释就太麻烦了!需要有一个变量,能够一键切换环境

二、改造配置文件

一键切换

conf.py

  1. #!/usr/bin/env python3
  2. # coding: utf-8
  3. # 配置文件
  4. import os
  5. class Config(object): # 默认配置
  6. DEBUG = False
  7. # get attribute
  8. def __getitem__(self, key):
  9. return self.__getattribute__(key)
  10. class ProductionConfig(Config): # 生产环境
  11. K8S_MASTER = "10.0.0.167"
  12. K8S_USERNAME = "root"
  13. K8S_PASSWD = "abcd@1234"
  14. class DevelopmentConfig(Config): # 开发环境
  15. K8S_MASTER = "192.168.0.162"
  16. K8S_USERNAME = "root"
  17. K8S_PASSWD = "root"
  18. # 环境映射关系
  19. mapping = {
  20. 'development': DevelopmentConfig,
  21. 'production': ProductionConfig,
  22. 'default': DevelopmentConfig
  23. }
  24. # 一键切换环境
  25. APP_ENV = os.environ.get('APP_ENV', 'default').lower() # 设置环境变量为default
  26. config = mapping[APP_ENV]() # 获取指定的环境

test.py 需要修改导入的模块

  1. #!/usr/bin/env python3
  2. # coding: utf-8
  3. # import conf
  4. from conf import config as conf
  5. def ssh2(ip,username,password,cmd): # 远程执行命令
  6. print(ip,username,password,cmd)
  7. return True
  8. res = ssh2(conf.K8S_MASTER,conf.K8S_USERNAME,conf.K8S_PASSWD,"uptime")
  9. print(res)

执行test.py,输出:

  1. 192.168.0.162 root root uptime
  2. True

现在需要切换环境,直接修改 conf.py 的倒数第二行

  1. APP_ENV = os.environ.get('APP_ENV', 'production').lower() # 设置环境变量为default
  2. config = mapping[APP_ENV]() # 获取指定的环境

再次执行test.py,输出:

  1. 10.0.0.167 root abcd@1234 uptime
  2. True

脚本执行切换

改conf.py切换环境,不够灵活,需要执行脚本时,带一个参数,由这个参数来决定环境,比如:

  1. python test.py dev

这样,就可以切换到开发环境!怎么做呢?

很简单,只需要修改conf.py即可!因为其他文件,都依赖于它

conf.py

  1. #!/usr/bin/env python3
  2. # coding: utf-8
  3. # 配置文件
  4. import os
  5. class Config(object): # 默认配置
  6. DEBUG = False
  7. # get attribute
  8. def __getitem__(self, key):
  9. return self.__getattribute__(key)
  10. class ProductionConfig(Config): # 生产环境
  11. K8S_MASTER = "10.0.0.167"
  12. K8S_USERNAME = "root"
  13. K8S_PASSWD = "abcd@1234"
  14. class DevelopmentConfig(Config): # 开发环境
  15. K8S_MASTER = "192.168.0.162"
  16. K8S_USERNAME = "root"
  17. K8S_PASSWD = "root"
  18. # 环境映射关系
  19. mapping = {
  20. 'dev': DevelopmentConfig,
  21. 'pro': ProductionConfig,
  22. 'default': DevelopmentConfig
  23. }
  24. # # 一键切换环境
  25. # APP_ENV = os.environ.get('APP_ENV', 'production').lower() # 设置环境变量为default
  26. # config = mapping[APP_ENV]() # 获取指定的环境
  27. # 根据脚本参数,来决定用那个环境配置
  28. import sys
  29. # print(sys.argv)
  30. num = len(sys.argv) - 1 #参数个数
  31. if num < 1 or num > 1:
  32. exit("参数错误,必须传环境变量!比如: python xx.py dev|pro|default")
  33. env = sys.argv[1] # 环境
  34. # print(env)
  35. APP_ENV = os.environ.get('APP_ENV', env).lower()
  36. config = mapping[APP_ENV]() # 实例化对应的环境

再次执行test.py

  1. python test.py

输出:

  1. 参数错误,必须传环境变量!比如: python xx.py dev|pro|default

切换到开发环境

  1. python test.py dev

输出:

  1. 192.168.0.162 root root uptime
  2. True

切换到生产环境

输出:

  1. 10.0.0.167 root abcd@1234 uptime
  2. True

本文参考链接:

https://blog.yuanbin.me/posts/2018-02/2018-02-24_16-30-16/