powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Rename Column и View
25 сообщений из 32, страница 1 из 2
Rename Column и View
    #40099603
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Господа, никто не подскажет - можно ли временно заблокировать изменение представления при переименовании поля в таблице?
...
Рейтинг: 0 / 0
Rename Column и View
    #40099622
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Транзакцию начни и вообще все изменения заблокируются, максимум читать можно будет и то до определенного момента. Так блокировка в SQLite работает.
...
Рейтинг: 0 / 0
Rename Column и View
    #40099636
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, чтение тут абсолютно ни при чем. Мне нужен скрипт, который изменяет параметры поля (например, тип или длину). У SQLite нет конструкции Alter Table Modify, поэтому мне нужно переименовать старое поле, добавить новое, скопировать данные из старого в новое и затем старое удалить. Но в момент переименования старого поля оно переименовывается также и во вьюхе. Мне нужно как-то заблокировать изменение вьюхи. Транзакция тут совершенно не помогает. Некорректная операция все равно вызывает ошибку, независимо от того, в рамках транзакции оно происходит или нет
...
Рейтинг: 0 / 0
Rename Column и View
    #40099650
little-brother
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
2.
3.
pragma legacy_alter_table = 1;
-- Добавляете новый столбец, удаляете старый
pragma legacy_alter_table = 0;
...
Рейтинг: 0 / 0
Rename Column и View
    #40099655
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
little-brother, спасибо, но, к сожалению, не то. Скрипт отрабатывает без ошибок, но представление меняется и после, естественно не работает
...
Рейтинг: 0 / 0
Rename Column и View
    #40099661
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
Dima T, чтение тут абсолютно ни при чем. Мне нужен скрипт, который изменяет параметры поля (например, тип или длину). У SQLite нет конструкции Alter Table Modify, поэтому мне нужно переименовать старое поле, добавить новое, скопировать данные из старого в новое и затем старое удалить. Но в момент переименования старого поля оно переименовывается также и во вьюхе. Мне нужно как-то заблокировать изменение вьюхи. Транзакция тут совершенно не помогает. Некорректная операция все равно вызывает ошибку, независимо от того, в рамках транзакции оно происходит или нет

Заблокировать изменение названия поля во вьюхе невозможно, т.к. нечего блокировать, в ней нет данных. Вьюха это запрос (select ...) который подставляется как подзапрос при выборке из нее. Синтаксический сахар.

Например есть вьюха V1
Код: sql
1.
select * from MyTable

Если ты переименовал в MyTable поле F1 в F1_old и сделал
Код: sql
1.
select * from V1 ...

то тут не будет F1 т.к. в реале это разворачивается в такую конструкцию
Код: sql
1.
select * from (select * from MyTable) V1 ...



Если тебе это мешает, значит в процессе переименования ты зачем-то обращаешься к представлению. Этого не надо делать. Обернув все изменения в общую транзакцию ты заставишь ждать остальных желающих обратиться к вью во время изменения таблицы.
...
Рейтинг: 0 / 0
Rename Column и View
    #40099666
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

-- Отключаем использование внешних ключей
PRAGMA foreign_keys = 0;

-- Переименовываем имеющееся поле
Alter Table `tbListVars` Rename Column `vcParentString` To `vcParentString_Old`;

-- Добавляем поле
Alter Table `tbListVars` Add `vcParentString` VarChar(1000) Default '…' Not Null;

-- Копируем данные в новое поле
Update `tbListVars` Set `vcParentString` = `vcParentString_Old`;

-- Удаляем старое поле
Alter Table `tbListVars` Drop Column `vcParentString_Old`;

-- Включаем использование внешних ключей
PRAGMA foreign_keys = 1;

Вот мой скрипт. Где именно я тут обращаюсь к представлению? Изменение идет в конкретной таблице. Но в тот момент, когда я переименовываю поле в таблице, в представлении это поле тоже переименовывается. Вполне возможно, что вьюха вида "Select * From `tbListVars`" не пострадает. Но меня такие вьюхи не устраивают, в моих необходимые поля перечисляются конкретно
...
Рейтинг: 0 / 0
Rename Column и View
    #40099667
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, это до переименования поля в таблице
...
Рейтинг: 0 / 0
Rename Column и View
    #40099668
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, а это после
...
Рейтинг: 0 / 0
Rename Column и View
    #40099674
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
Dima T,

-- Отключаем использование внешних ключей
PRAGMA foreign_keys = 0;

-- Переименовываем имеющееся поле
Alter Table `tbListVars` Rename Column `vcParentString` To `vcParentString_Old`;

-- Добавляем поле
Alter Table `tbListVars` Add `vcParentString` VarChar(1000) Default '…' Not Null;

-- Копируем данные в новое поле
Update `tbListVars` Set `vcParentString` = `vcParentString_Old`;

-- Удаляем старое поле
Alter Table `tbListVars` Drop Column `vcParentString_Old`;

-- Включаем использование внешних ключей
PRAGMA foreign_keys = 1;

Вот мой скрипт. Где именно я тут обращаюсь к представлению? Изменение идет в конкретной таблице. Но в тот момент, когда я переименовываю поле в таблице, в представлении это поле тоже переименовывается. Вполне возможно, что вьюха вида "Select * From `tbListVars`" не пострадает. Но меня такие вьюхи не устраивают, в моих необходимые поля перечисляются конкретно

Затестил, действительно меняет:
Код: sql
1.
2.
3.
4.
5.
6.
7.
create view vListVars
AS 
   select id, vcParentString from tbListVars;

... твой код

.schema vListVars


Результат
Код: plaintext
1.
2.
3.
CREATE VIEW vListVars
AS
   select id, "vcParentString_Old" from tbListVars
/* vListVars(id,"""vcParentString_Old""") */;

Тут только удалять вью и заново создавать
...
Рейтинг: 0 / 0
Rename Column и View
    #40099676
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, вот-вот. Причем сохранять скрипт вьюхи перед изменением таблицы, убивать ее, потом менять поле и только тогда создавать вьюху заново. Странно, что нет более простого способа. Жаль, конечно...
...
Рейтинг: 0 / 0
Rename Column и View
    #40099680
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
Dima T, вот-вот. Причем сохранять скрипт вьюхи перед изменением таблицы, убивать ее, потом менять поле и только тогда создавать вьюху заново. Странно, что нет более простого способа. Жаль, конечно...

Есть подозрение что эта проблема не только с вьюхами, а также с индексами и триггерами.
...
Рейтинг: 0 / 0
Rename Column и View
    #40099681
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, насчет триггеров не знаю, а с индексами проблем нет. Когда вьюхи на таблицу не существует, весь скрипт прекрасно выполняется. Индексы он обязан перестраивать при изменении таблицы
...
Рейтинг: 0 / 0
Rename Column и View
    #40099684
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Надо индекс удалять и создавать.

Затестил:
Код: sql
1.
2.
3.
4.
5.
create index iListVars on tbListVars (vcParentString);

... твой код

.schema


Наличие индекса не дает удалить vcParentString_Old
Код: sql
1.
Alter Table `tbListVars` Drop Column `vcParentString_Old`;


Код: plaintext
error in index iListVars after drop column: no such column: vcParentString_Old

Поэтому остаются оба поля с индексом по старому полю:
Код: plaintext
1.
CREATE TABLE tbListVars (id int primary key, "vcParentString_Old" VarChar(10), `vcParentString` VarChar(1000) Default ':' Not Null);
CREATE INDEX iListVars on tbListVars ("vcParentString_Old");
...
Рейтинг: 0 / 0
Rename Column и View
    #40099686
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, да, я, видимо, игрался с полями, по которым индексы не построены. В общем, сплошной гемор
...
Рейтинг: 0 / 0
Rename Column и View
    #40099751
little-brother
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
но представление меняется и после, естественно не работает
Да, попутал. Это только для имен таблиц работает, а не колонок (что собственно в названии и указано).

Если вы хотите изменить тип на схожий, напр. VARCHAR(20) на CHAR(30), которые по факту хранятся просто как TEXT, или изменить ограничение, которое и так выполняется в таблице, то можно попробовать изменить это прямо в файле переписав DDL, в обход библиотеки SQLite. Формат файла не слишком сложный, недавно я его тут описал, и если длины DDL хватит, то даже ячейку переносить не придется. Это конечно так себе метод.

Как вариант, попробовать спросить на форуме SQLite . Там то уж точно скажут возможно ли такое как то обойти или нет.
...
Рейтинг: 0 / 0
Rename Column и View
    #40099832
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
little-brother, что значит - для имен таблиц? Во многих инструкциях к таким операциям объясняют, что можно переименовать всю таблицу, создать новую с обновленной структурой, скопировать данные из старой в новую и убить старую. Вы имеете в виду, что при таком подходе не придется пересоздавать ни представления, ни индексы, ни триггеры?
...
Рейтинг: 0 / 0
Rename Column и View
    #40099841
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
S_Gur
little-brother, что значит - для имен таблиц? Во многих инструкциях к таким операциям объясняют, что можно переименовать всю таблицу, создать новую с обновленной структурой, скопировать данные из старой в новую и убить старую. Вы имеете в виду, что при таком подходе не придется пересоздавать ни представления, ни индексы, ни триггеры?


В общем-то, я попробовал этот метод и вьюха осталась неповрежденной. Индексы, конечно, придется пересоздавать, но это уже легче...
...
Рейтинг: 0 / 0
Rename Column и View
    #40099920
little-brother
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
что значит - для имен таблиц
То, что с колонками не прокатывает. Переименование колонки влечет её переименование во всех представлениях, индексах и триггерах. Для таблиц через указанную прагму такое поведение можно отменить.
...
Рейтинг: 0 / 0
Rename Column и View
    #40099935
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
little-brother,

https://runebook.dev/ru/docs/sqlite/pragma#pragma_legacy_alter_table

"PRAGMA legacy_alter_table;
PRAGMA legacy_alter_table = логическое

Эта прагма устанавливает или запрашивает значение флага legacy_alter_table. Когда этот флаг установлен, команда ALTER TABLE RENAME (для изменения имени таблицы) работает так же, как в SQLite 3.24.0 (2018-06-04) и ранее. Более конкретно, когда этот флаг установлен, команда ALTER TABLE RENAME перезаписывает только начальное вхождение имени таблицы в своем операторе CREATE TABLE и во всех связанных операторах CREATE INDEX и CREATE TRIGGER . Другие ссылки на таблицу без изменений, в том числе:

Ссылки на таблицу в телах триггеров и представлений.
Ссылки на таблицу в пределах ограничений CHECK в первоначальном заявлении CREATE TABLE.
Ссылки на таблицу в разделах WHERE частичных индексов ."

Триггера в блоке Create она все-таки ломает
...
Рейтинг: 0 / 0
Rename Column и View
    #40099969
little-brother
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, пропустил, что на триггерах не отключается. Поэтому видимо с триггерами, да и с представлениями, проще дропнуть всё, переименовать как надо и создать заново. Это не индексы пересоздадутся быстро, но вот если что-то пойдет не так, то увы :( Помнится SQLite Administrator меня с этим радовал (тогда я был не в курсе, что там всего лишь эмуляция переименования).
...
Рейтинг: 0 / 0
Rename Column и View
    #40099973
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
little-brother, представления надо убивать, только если имя поля меняется. Иначе все прекрасно живет. А вот индексы надо дропать точно, потому как имена индексов - особенно автоматические, если создавать неименованный индекс - не привязаны к имени таблицы, соответственно вряд ли они изменятся от переименования таблицы. Отсюда вытекает два постулата: 1 - желательно делать именованные индексы; 2 - перед созданием индекса лучше всего делать Drop Index If Exists
...
Рейтинг: 0 / 0
Rename Column и View
    #40099981
little-brother
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
имена индексов - особенно автоматические, если создавать неименованный индекс - не привязаны к имени таблицы
Пример можно? В DDL для индекса что имя его самого, что имя таблицы обязательны. Как это индекс может быть не привязан к таблице?

P.S. Вы свою задачу то решили?
...
Рейтинг: 0 / 0
Rename Column и View
    #40099995
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
little-brother, извиняюсь, оказывается соврал. Неименованные индексы привязаны к имени таблицы и переименовываются при переименовании самой таблицы. Первичный ключ для таблицы `tbListVars` получает автоматом наименование sqlite_master_PK_tbListVars, при переименовании таблицы в `tbListVars_Old` он становится sqlite_master_PK_tbListVars_Old. Так что, все еще более упростилось (в том смысле, что убивать индексы не надо). Да, свою задачу я решил. Переименовываю нужную таблицу, создаю новую (для начала без индексов), переношу данные из старой в новую, удаляю старую (все старые индексы при этом убиваются сами) и снова создаю все индексы уже на новую таблицу. После pragma legacy_alter_table = 0; пробую прочитать данные из вьюхи - все работает (естественно, при условии, что у изменяемого поля не меняется наименование)

Я говорил про имена индексов. В DDL для индекса что имя его самого, что имя таблицы обязательны, но можно написать:

`iID` Integer Unsigned Default 0 Not Null Constraint `pkListVars_ID` Primary Key,
`iParentID` Integer Unsigned Default 0 Not Null Constraint `fkListVars_ParentID` References `tbListVars`(`iID`) On Delete Cascade,

а можно:
`iID` Integer Unsigned Default 0 Not Null Primary Key,
`iParentID` Integer Unsigned Default 0 Not Null References `tbListVars`(`iID`) On Delete Cascade,

Во втором случае индексы получат наименование автоматически. Соответственно, можно при создании новой таблицы сразу создавать все индексы, предварительно убивая существующие. А можно сначала удалить старую таблицу, и только потом навесить индексы на новую. Видимо, в данном случае удобнее этот вариант
...
Рейтинг: 0 / 0
Rename Column и View
    #40100005
S_Gur
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
little-brother, экспериментальным путем выяснилось, что первичные и внешние ключи вообще плюют на задаваемое в конструкции Constraint имя и всегда именуются автоматически. Ошибки при этом не возникает, выражение Constraint [index_name] просто игнорируется
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Rename Column и View
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]