Переименование приложения с Django и South
Я переименовываю приложение в более подходящее имя. При этом я хочу убедиться, что South правильно переносит базу данных (переименовывает таблицы базы данных и ссылается на ссылки в django_content_type или south_migrationhistory). Я знаю, как переносить модель в другое приложение, но когда я пытаюсь переименовать приложение, Юг не распознает историю миграции должным образом.
Нежелательное решение: при переименовании old_app
в new_app
я могу оставить old_app/migrations
неповрежденным и добавить новые миграции в этот каталог, чтобы перенести базу данных на ссылку new_app
.
Если возможно, я бы предпочел полностью удалить каталог old_app
. Я еще не думал о лучшем решении этой проблемы.
Каков наилучший способ переименовать приложение с Django South без потери данных?
Ответы
Ответ 1
Я согласен с Лакшамом, что вам следует избегать этой ситуации. Но иногда мы должны это делать. Я сталкиваюсь с этой ситуацией и продолжаю этот путь.
Если вы хотите избежать потери данных, вы можете сбросить старые данные приложения в файл json.
python manage.py dumpdata old_app --natural --indent=4 1> old_app.json
Обратите внимание на параметр --natural, который заставит типы контента экспортироваться с помощью их естественных ключей (имя_приложения, модель)
Затем вы можете создать небольшую команду для открытия этого json файла и заменить все ссылки old_app на new_app.
Что-то вроде этого должно работать
class Command(BaseCommand):
help = u"Rename app in json dump"
def handle(self, *args, **options):
try:
old_app = args[0]
new_app = args[1]
filename = args[2]
except IndexError:
print u'usage :', __name__.split('.')[-1], 'old_app new_app dumpfile.json'
return
try:
dump_file = open(filename, 'r')
except IOError:
print filename, u"doesn't exist"
return
objects = json.loads(dump_file.read())
dump_file.close()
for obj in objects:
obj["model"] = obj["model"].replace(old_app, new_app, 1)
if obj["fields"].has_key("content_type") and (old_app == obj["fields"]["content_type"][0]):
obj["fields"]["content_type"][0] = new_app
dump_file = open(filename, 'w')
dump_file.write(json.dumps(objects, indent=4))
dump_file.close()
Затем переименуйте приложение, измените имя в INSTALLED_APPS.
Затем вы должны удалить все южные миграции, восстановить и применить первоначальную миграцию для нового приложения. Затем запустите команду SQL:
update django_content_type set app_label='new_app' where app_label='old_app'
Затем запустите южный переход для нового приложения, чтобы создать таблицы и загрузить json файл.
python manage.py loaddata old_app.json
Я сделал что-то подобное в проекте и, похоже, работает нормально.
Я надеюсь, что это поможет
Ответ 2
Можно переименовать приложение.
В качестве примера проекта см.:
https://github.com/ASKBOT/django-south-app-rename-example
В принципе, есть 2 миграции. Сначала таблицы переименовываются с помощью db.rename_table()
, а затем обновляются типы контента.
Это можно объединить в одну миграцию, проверив для if not db.dry_run:
. См. Как перенести модель из одного приложения django и в новый? для примера.
Для начальных миграций вы можете напрямую переименовать существующие таблицы, если они есть:
if 'old_app_table_name' in connection.introspection.table_names():
db.rename_table('old_app_table_name', 'new_app_table_name')
else:
# Create new app tables directly.
Для таблиц с большим количеством перемещений вам может потребоваться проверить, было ли уже применено старое имя миграции:
from south.models import MigrationHistory
if MigrationHistory.objects.exists(app_name='old_app', migration='0001_initial'):
return
Наконец, я рекомендую использовать IDE (например, пробную версию PyCharm) для переименования пакета (щелчок правой кнопкой мыши, рефакторинг → переименование в пакете), поскольку он обновит все используемые вами приложения, включая URLconf, настройки и импорт.
Ответ 3
После некоторого затыкания я придумал это. Должен позаботиться об этом.
https://gist.github.com/jamesmfriedman/6168003
Ответ 4
Отказ от ответственности: этот ответ предназначен для тех, кто не заботится о истории миграции и уже перепутал, переименовав приложение, полностью забыв о миграции (как и я).
Работал для меня.
После изменения имени папки, касающейся всего импорта в вашем коде и изменения имени соответствующего приложения в settings.INSTALLED_APPS, просто удалите всю предыдущую папку миграции. Затем сделайте начальную, подобную этой
manage.py schemamigration new_app --initial
Затем, применяя его, подделывайте его так:
manage.py migrate new_app 0001 --fake
Не забудьте сделать это, иначе вы можете потерять данные
Все дальнейшие миграции будут работать просто отлично
manage.py migrate new_app 0002
Также вы можете удалить из south_migrationhistory, где app_name = "old_app"
Ответ 5
Я бы не возился с именами приложений. Вы буквально называете имена приложений. URL confs, настройки, другие приложения, шаблоны и т.д.
Как проектируется django, соответственно на юг, предполагается, что нет необходимости изменять имена приложений. - Назовите свои проекты тем, что вы хотите. Вы не обращаетесь к нему нигде. Изменение имен приложений является громоздким. Ваше нежелательное решение - лучшее решение, которое я вижу, если вы действительно хотите переименовать свое приложение.
Для чего вам стоит использовать python import as
, чтобы импортировать приложение под другим именем, если вы этого хотите.