繁体   English   中英

Django South:检测是否在生产中应用了虚假迁移

[英]Django South: detecting if fake migrations were applied in production

我正在将South添加到具有许多安装的现有应用程序中,但由于安全原因,我无法访问生产环境。
我们只能提供Python安装脚本,这些脚本将由通常不了解Django,South等的人员运行。

我知道对于现有安装,任何未来的升级都必须从执行开始:

manage.py syncdb
manage.py migrate --all 0001 --fake

任何新安装都将从以下开始:

manage.py syncdb
manage.py migrate -all


有没有办法检测是否已经应用了南方初始迁移(例如,通过检测是否存在south_migfationhistory表)以数据库无关的方式(可能使用Django本身)?
我想做的是:

(pseudocode)
db = database.connect(dbname, user, password)
if db.table_existst('south_migrationhistory'):
  execute 'manage.py syncdb'
  execute 'manage.py migrate --all'
else:
  execute 'manage.py syncdb'
  execute 'manage.py migrate --all 0001 --fake'
  execute 'manage.py migrate --all'

为了将来参考,这是我最终这样做的方式:

if args.settings_dir not in sys.path:
  sys.path.append(args.settings_dir)

os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

#try to query db for existing objects, e.g. user groups
#in order to detect if we are upgrading an existing installation
from django.db.utils import DatabaseError
try:
  from django.contrib.auth.models import Group
  tmp = len(Group.objects.all()) #evaluate to force db query
  updating = True
except DatabaseError as e:
  updating = False

#try to query db for South migrations in order to detect if South was already applied
#in this installation (if not then accessing MigrationHistory will throw an excepion)
try:
  from south.models import MigrationHistory
  has_south = bool(len(MigrationHistory.objects.all()))
except ImportError as e:
  print 'ERROR: Error importing South migration history: ' + str(e)
  print 'Exiting'
  exit(1)
except DatabaseError as e:
  has_south = False

#syncdb to create south_migrationhistory table, portal models will not be synced
from django.core.management import execute_from_command_line
argv = ['manage.py', 'syncdb', '--settings=settings', '--pythonpath=' + args.settings_dir]
execute_from_command_line(argv)

#if we are updating existing installation and South wasn't already applied
#then initial migration has to be 'faked' in order to sync with existing tables
if updating and not has_south:
  print 'INFO: Faking initial database migration...'
  argv = ['manage.py', 'migrate', '--all', '0001', '--fake',
          '--settings=settings', '--pythonpath=' + args.settings_dir]
  execute_from_command_line(argv)

#run normal migrations
print 'INFO: Applying database migrations...'
argv = ['manage.py', 'migrate', '--all',
        '--settings=settings', '--pythonpath=' + args.settings_dir]
execute_from_command_line(argv)

解决您的情况实际上是南方的优秀票:

http://south.aeracode.org/ticket/430

--autofake-first单建议创建一个标志--autofake-first ,它将确定是否存在任何初始表,如果存在,将伪造第一次迁移,但正常运行其余的。 如果您刚刚将应用程序转换为South,这是完美的,但您需要将此更改作为远程或持续部署策略的一部分。

它已经开放了3年,虽然已经实施了一段时间,但它正在等待合并。 如果你想要这个功能,请随意评论这个问题;-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM