简体   繁体   English

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

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

I'm adding South to an existing application which has many installations however I don't have access to production environments due to security reasons. 我正在将South添加到具有许多安装的现有应用程序中,但由于安全原因,我无法访问生产环境。
We can only supply Python installation script that will be run by persons that often don't have any knowledge about Django, South, etc. 我们只能提供Python安装脚本,这些脚本将由通常不了解Django,South等的人员运行。

I'm aware of the fact that for existing installations any future upgrade will have to start with executing: 我知道对于现有安装,任何未来的升级都必须从执行开始:

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

and any new installations will start with: 任何新安装都将从以下开始:

manage.py syncdb
manage.py migrate -all


Is there any way to detect if south initial migrations were already applied (eg by detecting if south_migfationhistory table exists) in a database agnostic way (perhaps with Django itself) ? 有没有办法检测是否已经应用了南方初始迁移(例如,通过检测是否存在south_migfationhistory表)以数据库无关的方式(可能使用Django本身)?
What I would like to do is: 我想做的是:

(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'

For future reference this is how I ended up doing this: 为了将来参考,这是我最终这样做的方式:

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)

A solution to your situation is actually an outstanding ticket for South: 解决您的情况实际上是南方的优秀票:

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

The ticket suggests creating a flag --autofake-first , which will determine whether any initial tables exist, and if they do, will fake the first migration but run the rest as normal. --autofake-first单建议创建一个标志--autofake-first ,它将确定是否存在任何初始表,如果存在,将伪造第一次迁移,但正常运行其余的。 This is perfect if you've just converted an app to South, but you need this change as part of a remote or continuous deployment strategy. 如果您刚刚将应用程序转换为South,这是完美的,但您需要将此更改作为远程或持续部署策略的一部分。

It's been open for 3 years, and while it's been implemented for a while, it is waiting on being merged. 它已经开放了3年,虽然已经实施了一段时间,但它正在等待合并。 Feel free to comment on the issue if you'd like this functionality ;-) 如果你想要这个功能,请随意评论这个问题;-)

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

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