Повторяющееся значение ключа нарушает ограничение уникальности entity framework

Обновлено: 07.07.2024

Настройка типов столбцов

Ранее, при рассмотрении примера использования Code-First, вы уже видели использование некоторых атрибутов метаданных, которые позволяли настраивать тип данных столбца в таблице базы данных и применять к нему ограничения (например, указав поддерживает ли он NULL-значения). Далее мы рассмотрим эти атрибуты более подробно.

Ограничение длины

В таблице ниже показаны соглашения об ограничении длины столбцов, их реализация в виде аннотаций и в Fluent API:

В настройках модели можно указывать ограничение на максимальную длину для свойств, имеющих тип String или byte[], которые отображаются в таблице на соответствующие типы NVARCHAR и VARBINARY. По умолчанию Code-First задает для них максимальную длину NVARCHAR(max) и VARBINARY(max).

Ограничение длины можно наложить на строки или массивы байт. Согласно соглашениям, Code-First использует только ограничение максимальной длины, это означает, что SQL Server устанавливает тип данных для строк и массивов байт как NVARCHAR(n) и VARBINARY(n), где n – это длина, указанная в ограничении. По умолчанию, если к свойствам модели не использовалось ограничение по длине, Code-First установит максимально возможную длину столбцов – NVARCHAR(max) и VARBINARY(max).

Стоит обратить внимание, что указать максимальную и минимальную длину поля можно в одном атрибуте StringLength, используя именованные параметры этого атрибута. В следующем примере показано использование ограничения по длине с помощью аннотаций (здесь мы используем пример модели, который создали в статье “Использование Code-First” ранее):

А в следующем коде аналогичная настройка производится с помощью Fluent API (напомню, что для использования этого API-интерфейса необходимо переопределить метод настройки конфигурации OnModelCreating() в классе контекста, которым в нашем примере является класс SampleContext):

Явное указание типа столбца

Тип данных столбца в базе по умолчанию определяется поставщиком базы данных, которую вы используете. В SQL Server тип String в свойстве модели отражается на тип NVARCHAR в таблице базы данных, тип byte[] отражается на тип VARBINARY и т.д. В настройках модели можно явно указывать тип данных, который будет использоваться в таблице.

Как описывалось ранее, Entity Framework автоматически отображает типы данных модели на SQL-совместимые типы данных. Code-First позволяет управлять этим процессом, для того чтобы явно указать тип данных для столбца, как показано в примере ниже:

Поддержка NULL-значений для столбца

Entity Framework автоматически указывает для типов string и byte[] поддержку NULL в таблице базы данных, а для типов значений (int, long, …), DateTime, char, bool поддержку NOT NULL.

В примере ниже показано использование этих настроек, для конфигурирования информации об обнуляемых или не обнуляемых типах в таблице базы данных:

Обратите внимание, что в Fluent API можно настроить только поддержку NOT NULL для ссылочных типов данных, и нельзя настроить поддержку NULL для типов значений, т.к. поддержка NULL для них указывается явно, при объявлении типа свойства в классе модели.

Установка первичных ключей

Entity Framework ищет свойства модели имеющие имя Id или состоящие из строки “[TypeName] + Id”, например CustomerId для нашего примера и автоматически устанавливает их как первичные ключи в таблице базы данных.

Entity Framework требует, чтобы каждый класс сущностной модели имел уникальный ключ (т.к. для каждой таблицы в реляционной базе данных должен использоваться первичный ключ). Этот ключ используется в объекте контекста, для отслеживания изменений в объектах модели. Code-First делает некоторые предположения, при поиске ключа в таблице. Например, когда мы сгенерировали базу данных для классов сущностей Customer и Order ранее, при рассмотрении подхода Code-First, то Entity Framework пометил поля CustomerId и OrderId в таблицах, как первичные ключи и задал для них поддержку не обнуляемых типов:

Автоматически сгенерированные первичные ключи для таблиц

Также EF автоматически добавил поддержку автоинкремента в эти поля (напомню, что в T-SQL это делается с помощью инструкции IDENTITY). Чаще всего, первичные ключи в базе данных имеют тип INT или GUID, хотя любой примитивный тип может быть использован в качестве первичного ключа. Первичный ключ в базе данных может состоять из нескольких столбцов таблицы, аналогично, ключ сущностной модели EF может быть составлен из нескольких свойств модели. Позже вы увидите как настроить составные ключи.

Явная установка первичных ключей

В случае двух наших классов Customer и Order беспокоиться об явном указании первичного ключа не стоит, т.к. мы используем свойства CustomerId и OrderId, которые соответствуют соглашению об именовании ключей - “[TypeName] + Id”. Давайте рассмотрим пример, в котором нужно явно указать первичный ключ. Добавьте в файл модели следующий простой класс:

Нашей целью является указать, что свойство Identifier в этом классе является первичным ключом таблицы. Как видите имя этого свойства не соответствует соглашению Entity Framework об именовании первичных ключей.

Добавьте в класс контекста SampleContext описание новой таблицы:

Ошибка Entity Framework при поиске первичного ключа в классе модели

Обратите внимание, что при использовании Fluent API метод HasKey() указывается после вызова метода Entity<T>(), а не после вызова Entity<T>().Property(), как это делалось в примерах выше, т.к. первичный ключ устанавливается на уровне таблицы, а не на уровне свойств.

Настройка автоинкремента для первичных ключей

Если свойство первичного ключа в модели имеет тип int, для него автоматически устанавливается счетчик в базе данных с помощью инструкции IDENTITY (1,1).

Как видно из таблицы, следуя соглашениям, Entity Framework указывает автоинкремент для свойств имеющих тип int. В созданной ранее таблице Project для первичного ключа указывается тип Guid, вследствие чего, EF не использует счетчик для этого поля, при создании таблицы в базе данных. Это показано на рисунке:

Отключение автоинкремента для столбца типа Guid

Давайте добавим в наш проект новую веб-форму, которую назовем DatabaseGenerated.aspx. В обработчике Page_Load добавьте следующий код, в котором мы добавляем новые данные в таблицу Project. В данном случае эти данные будут добавляться всякий раз, когда мы открываем страницу нашей веб-формы в браузере.

Запустите проект и откройте веб-форму DatabaseGenerated.aspx. В результате в таблицу Project добавится новая запись:

Идентификатор Guid без автоинкремента

Ни базе данных, ни Entity Framework не известно, что мы хотели бы создавать новый идентификатор Guid для каждой новой записи, поэтому будет автоматически создан идентификатор, содержащий одни нули. Если вы обновите страницу в браузере (фактически в данном случае код попытается вставить новую запись в таблицу), то Entity Framework вернет исключение SqlException, которое возникает из-за того, что мы пытаемся вставить запись имеющую идентификатор, который уже существует в таблице, т.е. в данном случае срабатывает ограничение первичного ключа – он должен быть уникальным для каждой новой записи.

В результате, чтобы решить данную проблему, нам бы потребовалось генерировать уникальный идентификатор Guid в коде. Таблицы, использующие автоинкремент для первичных ключей лишены такой дополнительной работы, т.к. для каждой новой вставляемой записи, счетчик создает новое значение для первичного ключа, извлекая значение первичного ключа для последней записи и прибавляя к нему 1 (если использовалась конструкция IDENTITY(1,1)).

Чтобы решить эту проблему для ключей, имеющих тип отличный от int, нужно использовать атрибут метаданных DatabaseGenerated, в конструкторе которого указывается перечисление DatabaseGeneratedOption, имеющее три возможных значения:

None

База данных не создает никакого уникального значения для первичного ключа. Фактически, с помощью этой опции можно отключить автоматическое добавление автоинкремента к первичным ключам типа int.

Identity

При вставке значений в таблицу база данных создаст уникальное значение для первичного ключа.

Computed

Аналогично Identity, за тем лишь исключением, что первичный ключ будет генерироваться не только при вставке записей в таблицу, но и при их обновлении.

Измените класс модели таким образом, чтобы указать базе данных возможность создавать уникальный первичный ключ:

Запустите пример проекта и несколько раз обновите страницу, чтобы вставить несколько записей в таблицу и убедиться, что исключение больше не генерируется. На рисунке ниже показаны данные, добавленные в таблицу:

Добавленные записи при использовании автоинкремента для столбца типа Guid

Обратите внимание на автоматически сгенерированные идентификаторы для проектов. Того же эффекта можно добиться, используя метод HasDatabaseGeneratedOption() в Fluent API:

Работа со сложными типами данных

В этом классе адрес проживания пользователя можно выделить в отдельный класс и сослаться на него:

По соглашениями Entity Framework разберет эту модель – как две отдельные таблицы. Но нашей целью является создание сложного типа из класса Address. Традиционный способ для создания сложного типа из класса Address представляет удаление идентификатора AddressId:

В дополнение к правилу, что сложный тип не должен иметь ключ, Code-First накладывает два других правила, которые должны быть выполнены для обнаружения сложного типа. Во-первых, сложный тип должен содержать только простые свойства. Во-вторых, в классе, который использует этот тип, не разрешается указывать тип коллекции для свойства сложного типа. Другими словами, если вы хотите использовать сложный тип Address в классе User, то свойство, имеющее этот тип, не должно быть помечено как List<Address> или использовать другую коллекцию.

Как показано на рисунке ниже, после запуска приложения Code-First распознает сложный тип и создает специальные поля в таблице User (не забудьте добавить объявление User в классе контекста):

Столбцы сложного типа в таблице

Обратите внимание, как поля, описывающие адрес пользователя, названы: ИмяСложногоТипа_ИмяСвойства. Это является соглашением Entity Framework по именованию сложных типов.

Настройка сложных типов в обход соглашениям Code-First

Выше было сказано, что класс, описывающий сложный тип, должен иметь только простые свойства (т.е. не ссылающиеся на другие объекты). Это соглашение можно преодолеть, используя все те же средства. Ниже показан пример, в котором был добавлен новый сложный тип UserInfo, ссылающийся на другой тип FullName:

Благодаря указанию Code-First на то, что UserInfo является сложным типом с помощью атрибута ComplexType, мы преодолели ограничение, накладываемое на сложные типы при использовании соглашения по умолчанию.

Стоит отметить, что Code-First позволяет настраивать сложные типы, также, как и обычные таблицы с использованием Fluent API или аннотаций. Ниже показан пример, для настройки сложного типа Address:

На рисунке ниже показана структура таблицы User. Здесь вы можете увидеть, как EF именует свойства сложных типов с ссылками внутри и то, что EF накладывает ограничение на поле StreetAddress:

Использование ограничений для сложных типов

Описание других настроек

В этом разделе мы кратко рассмотрим все оставшиеся настройки столбцов таблицы, которые используются довольно редко в силу своих специфических особенностей.

Столбцы типа Timestamp

Тип данных TIMESTAMP в T-SQL указывает столбец, определяемый как VARBINARY(8) или BINARY(8), в зависимости от свойства столбца принимать значения NULL. Для каждой базы данных система содержит счетчик, значение которого увеличивается всякий раз, когда вставляется или обновляется любая строка, содержащая ячейку типа TIMESTAMP, и присваивает этой ячейке данное значение. Таким образом, с помощью ячеек типа TIMESTAMP можно определить относительное время последнего изменения соответствующих строк таблицы. (ROWVERSION является синонимом TIMESTAMP.)

Само по себе значение, сохраняемое в столбце типа TIMESTAMP, не представляет никакой важности. Этот столбец обычно используется для определения, изменилась ли определенная строка таблицы со времени последнего обращения к ней. Это позволяет решать вопросы параллельного доступа к таблице базы данных, позволяя блокировать другие потоки, если текущий поток изменил значения в строке.

В Code-First для указания на то, что столбец должен иметь тип TIMESTAMP должен использоваться одноименный атрибут Timestamp в аннотациях или метод IsRowVersion() в Fluent API, как показано в примере ниже:

Менее распространенным способом, для обеспечения безопасности при работе с параллельными потоками, является указание проверки параллелизма для каждого столбца. Такой способ может еще использоваться в СУБД, не поддерживающих типы Timestamp/Rowversion. При работе таким образом, поток не проверяет, изменилась ли запись в таблице, а просто блокирует доступ к ней для других потоков, пока сам не завершит процесс записи. Для указания столбцов, которые должны пройти проверку на параллелизм, используется атрибут ConcurrencyCheck в аннотациях, либо метод IsConcurrencyToken() в Fluent API.

Изменение кодировки строк с Unicode на ASCII

По умолчанию Entity Framework преобразует все строковые типы данных модели, такие как string или char, в строковые типы данных SQL, использующие двухбайтовую кодировку Unicode – NVARCHAR или NCHAR. Вы можете изменить это поведение, и явно указать EF использовать однобайтовую кодировку ASCII – соответственно будут использоваться типы VARCHAR и CHAR. Для этого нужно использовать метод IsUnicode() с переданным ему логическим параметром false в Fluent API. Аннотации не предоставляют возможность настройки кодировки строк.

Настоятельно не рекомендую вам использовать эту настройку, если планируется хранить строковую информацию в базе данных в символах, не совместимых с ASCII (например, русские символы).

Указание точности для типа Decimal

Для указания точности для типа Decimal (количество цифр в числе) и масштаба (количество цифр справа от десятичной точки в числе) можно использовать метод HasPrecision() с передачей ему двух параметров, который используется в Fluent API. Аннотации данных в Code-First не предлагают альтернативы этому методу. По умолчанию Entity Framework устанавливает точность 18, а масштаб 2 для типов Decimal.

В примере ниже показано использование этого метода, для свойства Cost таблицы Project, которую мы создали ранее, при рассмотрении первичных ключей:

Можно ли определить уникальное ограничение для свойства, используя свободный синтаксис или атрибут? Если нет, каковы обходные пути?

У меня есть класс пользователя с первичным ключом, но я хотел бы убедиться, что адрес электронной почты также уникален. Возможно ли это без непосредственного редактирования базы данных?

Решение (на основе ответа Мэтта)

Помните, что это ограничивает ваше приложение только базами данных, которые принимают этот точный синтаксис - в данном случае SQL Server. Если вы запустите свое приложение с поставщиком Oracle, оно завершится ошибкой. В этой ситуации мне нужно было бы только создать новый класс Initializer, но это верный момент.

Насколько я могу судить, на данный момент нет возможности сделать это с помощью Entity Framework. Однако это проблема не только с уникальными ограничениями . вы можете также создавать индексы, проверять ограничения и, возможно, триггеры и другие конструкции. Вот простой шаблон, который вы можете использовать с настройкой сначала кода, хотя, по общему признанию, он не зависит от базы данных:

Другой вариант: если ваша модель предметной области является единственным методом вставки / обновления данных в вашу базу данных, вы можете самостоятельно реализовать требование уникальности и не использовать базу данных. Это более переносимое решение, которое заставляет вас четко понимать свои бизнес-правила в коде, но оставляет вашу базу данных открытой для недопустимых данных.

Мне нравится, чтобы моя БД была жесткой как барабан, логика тиражируется на бизнес-уровне. Ваш ответ работает только с CTP4, но я на правильном пути, я предоставил решение, совместимое с CTP5, ниже моего исходного вопроса. Большое спасибо! Если ваше приложение не является однопользовательским, я считаю, что уникальное ограничение - это то, что вы не можете реализовать только с помощью кода. Вы можете значительно снизить вероятность нарушения в коде (проверяя уникальность перед вызовом SaveChanges() ), но все же существует вероятность проскальзывания еще одной вставки / обновления между временем проверки уникальности и временем SaveChanges() . Итак, в зависимости от того, насколько критично приложение и вероятность нарушения уникальности, вероятно, лучше всего добавить ограничение в базу данных. Вам нужно, чтобы ваш чек на уникальность был частью той же транзакции, что и ваши SaveChanges. Предполагая, что ваша база данных совместима с кислотами, вы должны иметь возможность таким образом обеспечить уникальность. Другой вопрос, позволяет ли EF правильно управлять жизненным циклом транзакции таким образом. EntityFramework 6.1.0 теперь поддерживает IndexAttribute, который вы можете добавить поверх свойств.

Начиная с EF 6.1 теперь возможно:

Это даст вам уникальный индекс вместо уникального ограничения, строго говоря. Для большинства практических целей они одинаковы .

@Dave: просто используйте одно и то же имя индекса для атрибутов соответствующих свойств ( источника ). Обратите внимание , это создает уникальный индекс , а не уникальный contraint . Хотя они почти одинаковы, они не совсем такие же (насколько я понимаю, уникальные ограничения могут использоваться в качестве цели FK). Для ограничения вам нужно выполнить SQL. (После последнего комментария) Другие источники предполагают, что это ограничение было снято в более поздних версиях SQL Server . но BOL не полностью согласован. @Richard: также возможны уникальные ограничения на основе атрибутов (см. Мой второй ответ ), но не из коробки. @exSnake: Начиная с SQL Server 2008, уникальный индекс по умолчанию поддерживает одно значение NULL для каждого столбца. Если требуется поддержка нескольких значений NULL, потребуется отфильтрованный индекс, см. Другой вопрос .

На самом деле это не связано с этим, но в некоторых случаях может помочь.

Если вы хотите создать уникальный составной индекс, скажем, для двух столбцов, которые будут действовать как ограничение для вашей таблицы, то начиная с версии 4.3 вы можете использовать новый механизм миграции для этого:

Обычно вам нужно вставить такой вызов в один из сценариев миграции:

Приятно видеть, что в EF есть миграции в стиле Rails. Вот если бы я только мог запустить его на Mono. Разве у вас не должно быть DropIndex в процедуре Down ()? DropIndex("TableName", new[] < "Column1", "Column2" >);

Я делаю полный взлом, чтобы SQL выполнялся при создании базы данных. Я создаю свой собственный DatabaseInitializer и наследую от одного из предоставленных инициализаторов.

Это единственное место, где я мог бы вклиниться в свои операторы SQL.

Это из CTP4. Не знаю, как это работает в CTP5.

Спасибо, Келли! Я не знал об этом обработчике событий. Мое возможное решение помещает SQL в метод InitializeDatabase.

Просто пытаясь выяснить, есть ли способ сделать это, единственный способ, который я нашел до сих пор, заключался в том, чтобы обеспечить его сам, я создал атрибут, который будет добавлен к каждому классу, где вы указываете имя полей, которые должны быть уникальными:

Затем в своем классе я добавлю это:

Наконец, я добавлю метод в свой репозиторий, в метод Add или при сохранении изменений следующим образом:

Не слишком хорошо, так как нам нужно полагаться на размышления, но пока этот подход работает для меня! = D

Также в 6.1 вы можете использовать версию ответа @ mihkelmuur с свободным синтаксисом следующим образом:

Беглый метод не идеален, ИМО, но, по крайней мере, теперь он возможен.

Простой способ в Visual Basic с использованием EF5 Code First Migrations

Образец публичного класса

Атрибут MaxLength очень важен для уникального индекса строкового типа.

Запустите cmd: update-database -verbose

после запуска cmd: add-migration 1

в сгенерированном файле

На самом деле это более подходящий ответ, чем настраиваемый инициализатор БД.

Чтобы использовать это, просто поместите [Уникальный] в любое поле, которое вы хотите сделать уникальным. Для строк вам нужно будет сделать что-то вроде (обратите внимание на атрибут MaxLength):

потому что поле строки по умолчанию - nvarchar (max), и это не будет разрешено в ключе.

Для нескольких полей в ограничении вы можете:

Затем включите полезное расширение, чтобы получить имя таблицы базы данных из типа:

Затем инициализатор базы данных:

Сначала определите атрибут UniqueAttribute:

Затем улучшите свою модель, например

Наконец, создайте собственный DatabaseInitializer (в моей версии я воссоздаю БД при изменениях БД только в режиме отладки . ). В этом DatabaseInitializer индексы автоматически создаются на основе уникальных атрибутов:

Возможно, это поможет .

Если вы переопределите метод ValidateEntity в своем классе DbContext, вы также можете поместить туда логику. Преимущество здесь в том, что у вас будет полный доступ ко всем своим DbSet. Вот пример:

Если вы используете EF5 и у вас все еще есть этот вопрос, приведенное ниже решение решило его для меня.

Я использую сначала код, поэтому помещаю:

в сценарии миграции хорошо справились со своей задачей. Он также допускает значения NULL!

Используя подход EF Code First, можно реализовать поддержку уникальных ограничений на основе атрибутов, используя следующую технику.

Создайте атрибут маркера

Отметьте свойства, которые вы хотите сделать уникальными для объектов, например

Создайте инициализатор базы данных или используйте существующий для создания уникальных ограничений.

Настройте контекст базы данных для использования этого инициализатора в коде запуска (например, в main() или Application_Start() )

Решение похоже на решение Mheyman, но с упрощением, поскольку оно не поддерживает составные ключи. Для использования с EF 5.0+.

Решение Fluent Api:

Сегодня я столкнулся с этой проблемой и, наконец, смог ее решить. Я не знаю, правильный ли это подход, но, по крайней мере, я могу продолжать:

Используйте уникальный валидатор свойств.

ValidateEntity не вызывается в одной транзакции базы данных. Следовательно, могут существовать состояния гонки с другими объектами в базе данных. Вам нужно немного взломать EF, чтобы заставить транзакцию SaveChanges (и, следовательно, ValidateEntity ). DBContext не может открыть соединение напрямую, но ObjectContext может.

После прочтения этого вопроса у меня возник собственный вопрос в процессе попытки реализовать атрибут для обозначения свойств как уникальных ключей, таких как ответы Михкеля Мюура , Тобиаса Шиттковски и Мхеймана : Сопоставьте свойства кода Entity Framework с столбцами базы данных (CSpace в SSpace)

Я наконец-то пришел к этому ответу, который может отображать как скалярные, так и навигационные свойства до столбцов базы данных и создавать уникальный индекс в определенной последовательности, указанной в атрибуте. Этот код предполагает, что вы реализовали UniqueAttribute со свойством Sequence и применили его к свойствам класса сущности EF, которые должны представлять уникальный ключ сущности (отличный от первичного ключа).

Примечание. Этот код основан на версии EF 6.1 (или более поздней), которая EntityContainerMapping недоступна в предыдущих версиях.

Для тех, кто использует конфигурации с первым кодом, вы также можете использовать объект IndexAttribute как ColumnAnnotation и установить для его свойства IsUnique значение true.

Я следую в отношении вопрос, который я задавал ранее в котором я пытался найти преобразование из тупого / плохо написанного запроса mysql в postgresql. Думаю, мне это удалось. В любом случае, я использую данные, которые были вручную перемещены из базы данных mysql в базу данных postgres. Я использую запрос, который выглядит так:

у меня есть основания полагать, что это хорошо работает. Однако это привело к новому вопросу. Когда я пытаюсь подчиниться, я получаю ошибка от django, которая гласит:

однако попытка запустить это приводит к ошибке дубликата ключа. Фактическая ошибка в коде под.

Я проверил последовательности и тому подобное, и они, похоже, в порядке. На данный момент я не уверен, что делать - я предполагаю, что это что-то на конце Джанго, но я не уверен. Любая обратная связь будет высоко ценится!

это случилось со мной-оказывается, вам нужно повторно синхронизировать поля первичного ключа в Postgres. Ключом является оператор SQL:

похоже, что это известная разница в поведении между MySQL и SQLite (они обновляют следующий доступный первичный ключ даже при вставке объекта с явным идентификатором) бэкэнды и другие бэкэнды, такие как Postgres, Oracle, . (они не).

есть билет, описывающий тот же вопрос. Несмотря на то, что он был закрыт как недопустимый, он дает намек на то, что есть команда управления Django для обновления следующего доступного ключа.

для отображения SQL обновляет все следующие идентификаторы для приложения MyApp:

чтобы выполнить оператор, вы можете предоставить его в качестве входных данных для dbshell команды управления. Для bash вы можете ввести:

преимущество команд управления заключается в том, что абстрагирует базовый сервер БД, поэтому он будет работать, даже если позже будет перенесен на другой сервер.

в дополнение к zapphods ответ:

в моем случае индексирование было действительно неправильным, так как я удалил все миграции, и база данных, вероятно, 10-15 раз при разработке, поскольку я не был в стадии миграции чего-либо.

Я получал IntegrityError на finished_product_template_finishedproduct_pkey

я использовал pgadmin3 и для любого индекса был неправильным и бросал повторяющиеся ключевые ошибки, которые я перешел к constraints и переиндексация.

enter image description here

и потом переиндексирован.

enter image description here

Если вы вручную скопировали базы данных, вы можете запустить в проблема описана здесь.

повторяющееся значение ключа нарушает уникальное ограничение " inventory_part_pkey" Деталь: ключ (part_id)=(1) уже существует.

Как упоминалось ранее, запустите код ниже, чтобы получить команду SQL для сброса id-s:

в моем случае python manage.py sqlsequencereset MyApp | python manage.py dbshell не было работа

  • поэтому я скопировал сгенерированный оператор SQL.
  • затем открыл pgAdmin для postgreSQL и открыл мою БД.
  • нажал на 6. значок (выполнение произвольных SQL-запросов)
  • скопировал инструкцию, которая была сгенерирована.

в моем случае это было:

начать; Выберите setval (pg_get_serial_sequence ('"inventory_signup"', 'id'), coalesce (max ("id"), 1), max ("id") не равно null) из "inventory_signup"; Выберите setval (pg_get_serial_sequence ('"inventory_supplier"',' id'), coalesce (max ("id"), 1), max ("id") не равно null) из " inventory_supplier"; Совершить;

выполнил его с помощью F5.

это исправило все мои таблицы и, наконец, добавив новые записи в конец, не пытаясь добавить его в больше.

решение заключается в том, что вам нужно повторно синхронизировать поля первичного ключа, Как сообщает "Hacking Life", который написал пример кода SQL, но, как предложено "Ad N", лучше запустить команду Django sqlsequencereset чтобы получить точный код SQL, который вы можете скопировать и пройти или запустить с другой командой.

я протестировал этот код с помощью Питон3.6, Джанго 2.0 и PostgreSQL 10.

я столкнулся с этой ошибкой, потому что я неправильно передавал дополнительные аргументы методу save.

для всех, кто сталкивается с этим, попробуйте принудительное обновление с:

Если вы получаете ошибку, которую вы не можете передать force_insert и force_update в то же время вы, вероятно, передаете некоторые пользовательские аргументы неправильно, как и я.

если вы хотите сбросить ПК на всех ваших таблицах, как я, вы можете использовать PostgreSQL рекомендуемый способ:

после выполнения этого запроса вам нужно будет выполнить результаты запроса. Обычно я копирую и вставляю в блокнот. Затем я нахожу и заменяю "SELECT С SELECT и ;" С ; . Я копирую и вставляю в pgAdmin III и запускаю запрос. Он сбрасывает все таблицы в базе данных. Более "профессиональные" инструкции предоставляются по ссылке выше.

Ниже приведены мои модели сущностей: роль и пользователь. Где каждый пользователь связан с одной ролью.

Моя конечная точка выглядит так:

Обратите внимание, что после выполнения некоторой отладки новый пользователь, передаваемый из тела, проходит проверку ниже, что означает, что моя модель действительна:

Но в конце концов он попадает в блок catch и распечатывает исключение, упомянутое выше.

Похоже, он пытается создать роль, связанную с новым пользователем. Теперь я не знаю почему, потому что эта роль уже существует.

Что может быть причиной этой проблемы?

2 ответа

Я использую Devise gem для проекта RoR, и у меня есть проблема с ним. У меня есть пользователь наследования одной таблицы, который должен иметь email и пароль, но у меня также есть модель клиента, которая наследуется от модели пользователя, и эта модель никогда не будет иметь пароля и может иметь.

Я использую EF Core 2.0 и Postgres 9.6. Всякий раз, когда я вставляю данные, я получаю ошибку PostgresException: 23505: повторяющееся значение ключа нарушает уникальное ограничение PK_country При трассировке это выглядит так, как будто EF не генерирует столбец AutoIncrement моя модель public.

Это определенно что-то связанное с entity framework. Хотя я создаю нового пользователя, прикрепленного к существующей роли, я также пытаюсь воссоздать эту роль. Я перешел к пункту " и " и добавил следующие строки перед сохранением сущности, чтобы убедиться, что роль, прикрепленная к пользователю, использует тот же контекст базы данных, что и сохраняемый пользователь:

Теперь это работает.

Нужно ли мне делать это всегда, когда мне нужно сохранять объекты, которые ссылаются на другие объекты?

Похожие вопросы:

Я столкнулся со следующей ошибкой после попытки удалить кучу записей, а затем вставить новые: Error: SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint.

Я не понимаю, почему postgres поднимает: duplicate key value violates unique constraint Я пошел проверить таблицу в pgadmin, чтобы увидеть, действительно ли у таблицы есть дубликат, и посмотреть.

Этот вопрос был задан несколькими людьми, но моя проблема, похоже, заключается в другом. На самом деле я должен объединить одни и те же структурированные таблицы из разных баз данных в postgresql в.

Я использую Devise gem для проекта RoR, и у меня есть проблема с ним. У меня есть пользователь наследования одной таблицы, который должен иметь email и пароль, но у меня также есть модель клиента.

Я использую EF Core 2.0 и Postgres 9.6. Всякий раз, когда я вставляю данные, я получаю ошибку PostgresException: 23505: повторяющееся значение ключа нарушает уникальное ограничение PK_country При.

Я пытаюсь расширить модель пользователя django auth с помощью OneToOneField, но не могу решить эту проблему. двойное значение ключа нарушает ограничение уникальности users_profile_user_id_key.

Python 3.6 Django 2.0 У меня есть две модели: from django.contrib.contenttypes.fields import GenericRelation @python_2_unicode_compatible class Domain(models.Model): tool_result =.

У меня есть история таблиц, в которой я пишу журналы. Когда я хочу вставить журнал, я получаю ошибку: 23505:Duplicate ключа нарушает ограничение уникальности! Вот моя функция public static void.

Я столкнулся с этой проблемой, когда создавал свое приложение. Поэтому всякий раз, когда я добавляю первый комментарий, проблема не появляется, но когда я пытаюсь сделать это во второй раз, я.

Читайте также: