#sql #doctrine-orm #persistence #hydration
#sql #doctrine-orm #постоянство #гидратация
Вопрос:
У меня есть таблица PostgreSQL t
со столбцами t1
, t2
, …. Мне нужно отфильтровать коллекцию объектов, прежде чем удалять все объекты по Doctrine из соображений эффективности. Однако Criteria
класс Doctrine слишком ограничен, поскольку он должен работать на уровне объектов PHP (после гидратации) и на уровне SQL (после гидратации). Поэтому я решил создать представление SQL, которое по существу отражает таблицу T
и добавляет дополнительный динамический столбец, который вычисляет выражение на уровне SQL. Следовательно, у меня есть
CREATE VIEW v AS SELECT t.*, (t.t1 <> t.t2) AS flag FROM t AS t;
(Примечание: приведенное выше логическое выражение для flag
на самом деле намного сложнее. Здесь он служит заполнителем.)
Объект Doctrine T
связан с представлением вместо таблицы и имеет дополнительное поле $flag
. Я использую ORMChangeTrackingPolicy( "NOTIFY" )
этот класс сущностей таким образом, что поле $flag
никогда не помечается как грязное, а Doctrine никогда не включает его в UPDATE
оператор. На уровне PHP поле $flag
синхронизируется с полями, которые формируют логическое выражение, с помощью соответствующих методов получения / установки.
PosgreSQL поддерживает INSERT INTO
, UPDATE
и DELETE
в представлениях, если поля представлений являются элементарными выражениями одной и той же таблицы.
Проблема: если новая сущность сохраняется в первый раз, Doctrine включает поле $flag
в INSERT INTO
инструкцию, даже если $flag
оно помечено как не загрязненное. Это вызывает следующее исключение SQL: «ОШИБКА: не удается вставить в столбец «флаг» представления «v» ПОДРОБНЕЕ: столбцы представления, которые не являются столбцами их базового отношения, не подлежат обновлению».
Есть ли какой-либо способ указать Doctrine не включать этот столбец? Есть ли способ пометить столбец как доступный только для чтения?
Ответ №1:
Для тех, кто столкнулся бы с такой же проблемой, как я. Начиная с версии Doctrine >2.11
, @Column
в аннотации добавлены новые полезные опции (ссылка на документы) :
updatable
insertable
Поля с этими параметрами, установленными на false
, теперь игнорируются в сгенерированном SQL-запросе.