3

多くのインストールがある既存のアプリケーションにSouthを追加していますが、セキュリティ上の理由から本番環境にアクセスできません。
提供できるのは、DjangoやSouthなどの知識がないことが多い人が実行するPythonインストールスクリプトのみです。

既存のインストールの場合、将来のアップグレードは実行から開始する必要があるという事実を認識しています。

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

新しいインストールは次のように始まります。

manage.py syncdb
manage.py migrate -all


データベースにとらわれない方法で(おそらくDjango自体を使用して)南の初期移行がすでに適用されているかどうかを検出する方法はありますか(たとえば、south_migfationhistoryテーブルが存在するかどうかを検出することによって)?
私がしたいのは:

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

2 に答える 2

1

将来の参考のために、これは私がこれを行うことになった方法です:

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)
于 2013-01-17T10:43:32.237 に答える
0

あなたの状況に対する解決策は、実際には南の未解決のチケットです。

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

--autofake-firstチケットは、初期テーブルが存在するかどうかを判断するフラグを作成することを提案します。存在する場合は、最初の移行を偽造しますが、残りは通常どおり実行します。これは、アプリをSouthに変換したばかりの場合に最適ですが、リモートまたは継続的なデプロイ戦略の一環としてこの変更が必要です。

オープンして3年になりますが、しばらくは実装されていますが、統合されるのを待っています。この機能が必要な場合は、この問題についてお気軽にコメントしてください;-)

于 2013-10-08T04:31:50.783 に答える