Создание данных семян в миграциях с флягой или миграции

Как я могу вставить некоторые данные семян в первую миграцию? Если миграция не лучшее место для этого, то в чем лучшая практика?

"""empty message Revision ID: 384cfaaaa0be Revises: None Create Date: 2013-10-11 16:36:34.696069 """ # revision identifiers, used by Alembic. revision = '384cfaaaa0be' down_revision = None from alembic import op import sqlalchemy as sa def upgrade(): ### commands auto generated by Alembic - please adjust! ### op.create_table('list_type', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', sa.String(length=80), nullable=False), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('name') ) op.create_table('job', sa.Column('id', sa.Integer(), nullable=False), sa.Column('list_type_id', sa.Integer(), nullable=False), sa.Column('record_count', sa.Integer(), nullable=False), sa.Column('status', sa.Integer(), nullable=False), sa.Column('sf_job_id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('compressed_csv', sa.LargeBinary(), nullable=True), sa.ForeignKeyConstraint(['list_type_id'], ['list_type.id'], ), sa.PrimaryKeyConstraint('id') ) ### end Alembic commands ### # ==> INSERT SEED DATA HERE <== def downgrade(): ### commands auto generated by Alembic - please adjust! ### op.drop_table('job') op.drop_table('list_type') ### end Alembic commands ### 

3 Solutions collect form web for “Создание данных семян в миграциях с флягой или миграции”

Alembic, как одна из его операций, bulk_insert() . В документации приведен следующий пример (с некоторыми исправлениями, которые я включил):

 from datetime import date from sqlalchemy.sql import table, column from sqlalchemy import String, Integer, Date from alembic import op # Create an ad-hoc table to use for the insert statement. accounts_table = table('account', column('id', Integer), column('name', String), column('create_date', Date) ) op.bulk_insert(accounts_table, [ {'id':1, 'name':'John Smith', 'create_date':date(2010, 10, 5)}, {'id':2, 'name':'Ed Williams', 'create_date':date(2007, 5, 27)}, {'id':3, 'name':'Wendy Jones', 'create_date':date(2008, 8, 15)}, ] ) 

Заметим также, что у alembic есть операция execute() , которая похожа на обычную функцию execute() в SQLAlchemy: вы можете запустить любой SQL, который вы хотите, как показывает пример документации:

 from sqlalchemy.sql import table, column from sqlalchemy import String from alembic import op account = table('account', column('name', String) ) op.execute( account.update().\ where(account.c.name==op.inline_literal('account 1')).\ values({'name':op.inline_literal('account 2')}) ) 

Обратите внимание, что таблица, которая используется для создания метаданных, используемых в операторе update определяется непосредственно в схеме. Это может показаться, что он разбивает DRY (это не таблица, уже определенная в вашем приложении), но на самом деле совершенно необходима. Если вы попытаетесь использовать определение таблицы или модели, которое является частью вашего приложения, вы можете разбить эту миграцию, когда вы вносите изменения в свою таблицу / модель в своем приложении. Ваши сценарии миграции должны быть установлены в виде камня: изменение в будущей версии ваших моделей не должно изменять сценарии миграции. Использование моделей приложений будет означать, что определения будут меняться в зависимости от того, какую версию моделей вы проверили (скорее всего, последние). Поэтому вам необходимо, чтобы определение таблицы было самодостаточным в сценарии миграции.

Еще одна вещь, о которой стоит поговорить, заключается в том, следует ли помещать ваши данные семени в скрипт, который запускается как его собственная команда (например, с помощью команды Flask-Script, как показано в другом ответе). Это можно использовать, но вы должны быть осторожны. Если данные, которые вы загружаете, являются тестовыми данными, то это одно. Но я понял, что «данные семени» означают данные, необходимые для правильной работы приложения. Например, если вам нужно настроить записи для «admin» и «user» в таблице «role». Эти данные ДОЛЖНЫ быть вставлены как часть миграций. Помните, что сценарий будет работать только с последней версией вашей базы данных, тогда как миграция будет работать с конкретной версией, с которой вы переносите или из нее. Если вы хотите, чтобы скрипт загружал информацию о ролях, для скрипта для каждой версии базы данных может потребоваться сценарий с другой схемой для таблицы ролей.

Кроме того, полагаясь на сценарий, вам будет труднее выполнить сценарий между миграциями (например, для миграции 3> 4 требуется, чтобы начальные данные в начальной миграции были в базе данных). Теперь вам нужно изменить способ запуска Alembic по умолчанию для запуска этих сценариев. И это все еще не игнорирует проблемы с тем, что эти скрипты со временем должны будут меняться, и кто знает, какую версию вашего приложения вы проверили из источника управления.

Миграции должны быть ограничены только изменениями схемы, и не только это важно, чтобы при применении миграции вверх или вниз данные, которые существовали в базе данных ранее, сохраняются как можно больше. Вставка данных семян в часть миграции может испортить ранее существовавшие данные.

Как и большинство вещей с Flask, вы можете реализовать это разными способами. Добавление новой команды в Flask-Script – хороший способ сделать это, на мой взгляд. Например:

 @manager.command def seed(): "Add seed data to the database." db.session.add(...) db.session.commit() 

Итак, вы запускаете:

 python manager.py seed 

MarkHildreth предоставил отличное объяснение того, как алембик может справиться с этим. Тем не менее, ОП был конкретно о том, как изменить сценарий миграции миграции флагов. Я собираюсь опубликовать ответ на этот вопрос ниже, чтобы спасти людей от времени, чтобы взглянуть на alembic вообще.

Предупреждение . Ответ Мигеля является точным в отношении обычной информации о базе данных. То есть следует следовать его совету и абсолютно не использовать этот подход для заполнения базы данных «нормальными» строками. Этот подход специально предназначен для строк базы данных, которые необходимы для работы приложения, своего рода данные, которые я считаю «семенными» данными.

Сценарий OP изменен для обработки данных:

 """empty message Revision ID: 384cfaaaa0be Revises: None Create Date: 2013-10-11 16:36:34.696069 """ # revision identifiers, used by Alembic. revision = '384cfaaaa0be' down_revision = None from alembic import op import sqlalchemy as sa def upgrade(): ### commands auto generated by Alembic - please adjust! ### list_type_table = op.create_table('list_type', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', sa.String(length=80), nullable=False), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('name') ) op.create_table('job', sa.Column('id', sa.Integer(), nullable=False), sa.Column('list_type_id', sa.Integer(), nullable=False), sa.Column('record_count', sa.Integer(), nullable=False), sa.Column('status', sa.Integer(), nullable=False), sa.Column('sf_job_id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('compressed_csv', sa.LargeBinary(), nullable=True), sa.ForeignKeyConstraint(['list_type_id'], ['list_type.id'], ), sa.PrimaryKeyConstraint('id') ) ### end Alembic commands ### op.bulk_insert( list_type_table, [ {'name':'best list'}, {'name': 'bester list'} ] ) def downgrade(): ### commands auto generated by Alembic - please adjust! ### op.drop_table('job') op.drop_table('list_type') ### end Alembic commands ### 

Контекст для новых пользователей flask_migrate

Flask migrate генерирует сценарии migrations/versions при migrations/versions . Эти сценарии запускаются в порядке в базе данных, чтобы довести их до последней версии. OP включает пример одного из этих автоматически сгенерированных сценариев миграции. Чтобы добавить данные семян, необходимо вручную изменить соответствующий автоматически сгенерированный файл миграции. Код, который я опубликовал выше, является примером этого.

Что изменилось?

Очень мало. Вы заметите, что в новом файле я сохраняю таблицу, возвращенную из create_table для list_type в переменной, называемой list_type_table . Затем мы используем эту таблицу, используя op.bulk_insert чтобы создать несколько строк примеров.

  • Изменение данных как часть обновления alembic
  • Изменение поля Enum с использованием Alembic
  • Как выполнять вставки и обновления в сценарии обновления Alembic?
  • Alembic не добавляет информацию о каскаде в автогенератор?
  • sqlalchemy: alembic bulk insert failed: объект 'str' не имеет атрибута '_autoincrement_column'
  • alembic - пример использования ресурса пакета как script_location
  • как очистить незавершенный пробег
  • Как использовать предложение USING в Alembic / SQLAchemy?
  •  
    Interesting Posts for Van-Lav

    Чертежи, PyMongo в колбе

    Групповые данные по сезонам с использованием python и pandas

    Django: загруженные файлы не собираются с мусором, что вызывает проблемы с памятью

    Вычисление площади под кривой, заданной набором координат, не зная функции

    SqlAlchemy Left Присоединиться к счету

    numpy получить индекс, где значение истинно

    Хороший pythonic способ определить выбор полей модели django с дополнительными атрибутами и методами

    Плохой дескриптор файла – Heroku Foreman

    не может установить начальное значение для форм. ChoiceField в django

    Argparse неправильный порядок позиционных и необязательных параметров

    Ошибка выполнения Anaconda: Python не установлен как фреймворк?

    Показать значение по умолчанию для редактирования на входе Python возможно?

    % matplotlib line magic вызывает SyntaxError в скрипте Python

    Обновлена ​​(текущая) рекомендация по Rails по сравнению с Django?

    Python: что такое элегантная идиома для расширения метода с одним или несколькими аргументами ключевого слова?

    Python - лучший язык программирования в мире.