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