Doctrine2 не устанавливает последовательность по умолчанию для столбца id (postgres)
Простой пример: если я хочу создать таблицу с автозаполнением в postgres, я запустил этот sql:
CREATE SEQUENCE person_id_seq START 1;
CREATE TABLE person (
id integer PRIMARY KEY DEFAULT nextval('person_id_seq'),
name varchar(100) NOT NULL
);
и в доктрине я установил все свойство
class Person {
/**
* @Id
* @Column(type="integer", nullable=false)
* @GeneratedValue(strategy="SEQUENCE")
* @SequenceGenerator(sequenceName="person_id_seq", initialValue=1, allocationSize=100)
*/
private $id;
но когда я сгенерировал sql (доктрина php orm: schema-tool: create --dump-sql), я получил ее:
CREATE TABLE person (
id INT NOT NULL,
name VARCHAR(100) NOT NULL
);
CREATE SEQUENCE person_id_seq INCREMENT BY 100 MINVALUE 1 START 1
но не устанавливайте его по умолчанию
\ d человек
Column | Type | Modifiers
-------------------+--------------------------------+-----------
id | integer | not null
...
..
.
Ответы
Ответ 1
Из точное руководство:
4.8.1. Стратегии генерации идентификаторов
...
AUTO
(по умолчанию): Сообщает Doctrine о выборе стратегии, которая предпочтительнее используемой платформы баз данных. Предпочтительными стратегиями являются IDENTITY для MySQL, SQLite и MsSQL и SEQUENCE для Oracle и PostgreSQL. Эта стратегия обеспечивает полную мобильность.
...
IDENTITY
: указывает Doctrine на использование специальных столбцов идентификации в базе данных, которые генерируют значение при вставке строки. В настоящее время эта стратегия не обеспечивает полной переносимости и поддерживается следующими платформами: MySQL/SQLite (AUTO_INCREMENT), MSSQL (IDENTITY) и PostgreSQL (SERIAL).
Они предлагают AUTO
для максимальной переносимости:
/**
* @Id
* @Column(type="integer", nullable=false)
* @GeneratedValue
*/
Это должно создать и установить для вас последовательность. Альтернативой может быть запрос столбца serial
с использованием стратегии IDENTITY
:
/**
* @Id
* @Column(type="integer", nullable=false)
* @GeneratedValue(strategy="IDENTITY")
*/
Этот должен создать ваш столбец id
как тип serial
, а PostgreSQL создаст последовательность и настроит для вас значение по умолчанию.
Документация указывает, что то, что вы делаете, должно работать, но документация обычно обеспечивает только упрощенную версию действительности.
Попробуйте использовать strategy="AUTO"
. Если это не сработает, попробуйте strategy="IDENTITY"
.
Ответ 2
Сегодня я столкнулся с этой проблемой, и я обнаружил, что:
-
ИДЕНТИФИКАЦИЯ работает хорошо, потому что для PostgreSQL используется тип SERIAL, который автоматически создает связанную последовательность и устанавливает значение по умолчанию как nextval (sequence)
-
AUTO создает таблицу, а затем связанную последовательность, но не устанавливает значение по умолчанию для столбца id.
Его можно установить, добавив следующий код:
/**
* Webpage ID
*
* @ORM\Id
* @ORM\Column(type="integer", options={"default"="nextval('webpages_id_seq'::regclass)"})
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
но, к сожалению, Doctrine сначала создает таблицу, поэтому нам нужно поменять таблицу и последовательность создания кода SQL, чтобы первая последовательность была создана
-
SEQUENCE работает так же, как AUTO