Мне пришлось конвертировать из текста в uuid-тип и из миграции Django, поэтому после его решения я написал его в http://baltaks.com/2015/08/how-to-change-text-fields-to-a-real-uuid-type-for-django-and-postgresql в случае, если кто-то поможет. Те же методы будут работать для преобразования целого числа в uuid.
На основе комментариев, я добавил полное решение здесь:
Джанго, скорее всего, создать миграцию для вас, что выглядит примерно так:
class Migration(migrations.Migration):
dependencies = [
('app', '0001_auto'),
]
operations = [
migrations.AlterField(
model_name='modelname',
name='uuid',
field=models.UUIDField(db_index=True, unique=True),
),
]
Сначала ставят авто создана миграции операции в операцию RunSQL как параметр state_operations
. Это позволяет вам настроить пользовательскую миграцию, но сообщите Django о том, что произошло с схемой базы данных.
class Migration(migrations.Migration):
dependencies = [
('app', '0001_auto'),
]
operations = [
migrations.RunSQL(sql_commands, None, [
migrations.AlterField(
model_name='modelname',
name='uuid',
field=models.UUIDField(db_index=True, unique=True),
),
]),
]
Теперь вы должны будете предоставить некоторые команды SQL для этой sql_commands
переменной. Я решил поставить SQL в отдельный файл, а затем загрузить в со следующим кодом питона:
sql_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '0001.sql')
with open(sql_path, "r") as sqlfile:
sql_commands = sqlfile.read()
Теперь для реальной сложной части, где мы на самом деле выполнить миграцию. Основная команда, которую вы хотите выглядеть так:
alter table tablename alter column uuid type uuid using uuid::uuid;
Но причина, мы здесь из-индексов. И, как я обнаружил, Django любит использовать ваши миграции для создания случайно названных индексов в ваших полях во время выполнения тестов, поэтому ваши тесты не удастся, если вы просто удалите и затем заново создадите индекс фиксированного имени или два.Итак, следующее: sql, который удалит одно ограничение и все индексы в текстовом поле перед преобразованием в поле uuid. Он также работает для нескольких таблиц за один раз.
DO $$
DECLARE
table_names text[];
this_table_name text;
the_constraint_name text;
index_names record;
BEGIN
SELECT array['table1',
'table2'
]
INTO table_names;
FOREACH this_table_name IN array table_names
LOOP
RAISE notice 'migrating table %', this_table_name;
SELECT CONSTRAINT_NAME INTO the_constraint_name
FROM information_schema.constraint_column_usage
WHERE CONSTRAINT_SCHEMA = current_schema()
AND COLUMN_NAME IN ('uuid')
AND TABLE_NAME = this_table_name
GROUP BY CONSTRAINT_NAME
HAVING count(*) = 1;
if the_constraint_name is not NULL then
RAISE notice 'alter table % drop constraint %',
this_table_name,
the_constraint_name;
execute 'alter table ' || this_table_name
|| ' drop constraint ' || the_constraint_name;
end if;
FOR index_names IN
(SELECT i.relname AS index_name
FROM pg_class t,
pg_class i,
pg_index ix,
pg_attribute a
WHERE t.oid = ix.indrelid
AND i.oid = ix.indexrelid
AND a.attrelid = t.oid
AND a.attnum = any(ix.indkey)
AND t.relkind = 'r'
AND a.attname = 'uuid'
AND t.relname = this_table_name
ORDER BY t.relname,
i.relname)
LOOP
RAISE notice 'drop index %', quote_ident(index_names.index_name);
EXECUTE 'drop index ' || quote_ident(index_names.index_name);
END LOOP; -- index_names
RAISE notice 'alter table % alter column uuid type uuid using uuid::uuid;',
this_table_name;
execute 'alter table ' || quote_ident(this_table_name)
|| ' alter column uuid type uuid using uuid::uuid;';
RAISE notice 'CREATE UNIQUE INDEX %_uuid ON % (uuid);',
this_table_name, this_table_name;
execute 'create unique index ' || this_table_name || '_uuid on '
|| this_table_name || '(uuid);';
END LOOP; -- table_names
END;
$$
Я получаю «ОШИБКА: функция uuid_generate_v4() не существует». Есть ли какие-то дополнения, которые мне нужны? – user1802143
@ user1802143 Да, см. Редактирование. Или Google ;-) –
'ОШИБКА: значение по умолчанию для столбца« Идентификатор »не может быть автоматически добавлено для ввода uuid Состояние SQL: 42804' при запуске команды, добавление швов столбцов является единственным рабочим вариантом – konzo