Измените размер строкового столбца Postres в Heroku с помощью перегонного куба

Я хочу изменить размер столбца String в моей базе данных PostgreSQL с помощью перегонного куба.

Моя первая попытка в моей локальной БД была более простой и логичной:

Измените размер поля db.Column, которое я хотел изменить, и настроить alembic для поиска изменений типа, как указано здесь: добавьте параметр compare_type=True к context.configure() моего alembic/env.py. А затем запустите alembic revision --autogenerate, который правильно сгенерировал файл с вызовом alter_column.

Кажется, это нормально, но alembic upgrade head занимало так много времени из-за столбца alter, что я отменил выполнение и искал другие решения, поскольку я думаю, что если это займет так много времени на моем компьютере, это займет много времени и на сервере Heroku, и Я не собираюсь приостанавливать свою службу, пока эта операция не будет завершена.

Поэтому я придумал довольно хакерский решение, которое отлично работало на моей машине:

Я создал оператор обновления в файле перегонного куба для обновления и понизить:

connection = op.get_bind()


def upgrade():
    connection.execute("update pg_attribute SET atttypmod = 1000+4" + \
                       "where attrelid = 'item'::regclass and attname = 'details'", execution_options=None)


def downgrade():
    connection.execute("update pg_attribute SET atttypmod = 200+4" + \
                       "where attrelid = 'item'::regclass and attname = 'details'", execution_options=None)

И работал очень быстро в моей машине. Но при отправке его в мое промежуточное приложение в Heroku и выполнении обновления было предложено ERROR: permission denied for relation pg_attribute. То же самое произойдет, если я попытаюсь выполнить оператор обновления непосредственно в psql. Я предполагаю, что это намеренно от Heroku, и что я не должен обновлять такие таблицы, так как я могу нарушить работу базы данных, если сделаю это неправильно. Я предполагаю, что форсировать это обновление в Heroku - не выход.

Я также попытался создать новый временный столбец, скопировав все данные из старого-маленького столбца в этот временный, удалил старый столбец, создал новый с тем же именем, что и старый, но с желаемым размером, скопировал данные из столбца temp и удалил его следующим образом:

def upgrade():
    op.add_column('item', sa.Column('temp_col', sa.String(200)))
    connection.execute("update item SET temp_col = details", execution_options=None)
    op.drop_column('item', 'details')
    op.add_column('item', sa.Column('details', sa.String(1000)))
    connection.execute("update item SET details = temp_col", execution_options=None)
    op.drop_column('item', 'temp_col')


def downgrade():
    op.add_column('item', sa.Column('temp_col', sa.String(1000)))
    connection.execute("update item SET temp_col = details", execution_options=None)
    op.drop_column('item', 'details')
    op.add_column('item', sa.Column('details', sa.String(200)))
    connection.execute("update item SET details = temp_col", execution_options=None)
    op.drop_column('item', 'temp_col')

Но это также занимает много времени и не кажется действительно аккуратным способом сделать это.

Итак, мой вопрос: как правильно изменить размер строкового столбца в postgreSQL в Heroku с помощью перегонного куба, не ожидая целую вечность, пока будет выполнено изменение столбца?


person josebama    schedule 21.02.2014    source источник
comment
Почему бы просто не выполнить alter table T alter column C type text и оставить проверку длины для ограничения CHECK? В любом случае PostgreSQL обрабатывает их все как ТЕКСТ с внутренними условиями.   -  person mu is too short    schedule 21.02.2014
comment
Я не знал о типе текстового поля, теперь я буду использовать его. Но таблица изменений все еще занимает целую вечность с перегонным кубом. Похоже, моя проблема связана с перегонным кубом. Тогда я собираюсь отредактировать свой вопрос и выполнить таблицу изменений в командной строке. Но я все же хотел бы знать, как правильно это сделать с помощью перегонного куба, чтобы вести учет всех изменений в базе данных.   -  person josebama    schedule 22.02.2014
comment
Боюсь, вам придется жить с длинным ALTER; Я не думаю, что механизм ограничений Pg оптимизирует случай увеличения длины ограничения длины varchar. Можно с уверенностью предположить, что ограничение уже действительно и не требует перепроверки ALTER, но я так не думаю.   -  person Craig Ringer    schedule 22.02.2014