Ошибка more than one owned sequence found

Update: This bug has been fixed in PostgreSQL v12 with commit 19781729f78.
The rest of the answer is relevant for older versions.

A serial column has a sequence that is owned by the column and a DEFAULT value that gets the net sequence value.

If you try to change that column into an identity column, you’ll get an error that there is already a default value for the column.

Now you must have dropped the default value, but not the sequence that belongs to the serial column. Then when you converted the column into an identity column, a second sequence owned by the column was created.

Now when you try to insert a row, PostgreSQL tries to find and use the sequence owned by the column, but there are two, hence the error message.

I’d argue that this is a bug in PostgreSQL: in my opinion, it should either have repurposed the existing sequence for the identity column or given you an error that there is already a sequence owned by the column, and you should drop it. I’ll try to get this bug fixed.

Meanwhile, you should manually drop the sequence left behind from the serial column.
Run the following query:

SELECT d.objid::regclass
FROM pg_depend AS d
   JOIN pg_attribute AS a ON d.refobjid = a.attrelid AND
                             d.refobjsubid = a.attnum
WHERE d.classid = 'pg_class'::regclass
  AND d.refclassid = 'pg_class'::regclass
  AND d.deptype <> 'i'
  AND a.attname = 'patientid'
  AND d.refobjid = 'patient'::regclass;

That should give you the name of the sequence left behind from the serial column. Drop it, and the identity column should behave as desired.

Update: This bug has been fixed in PostgreSQL v12 with commit 19781729f78.
The rest of the answer is relevant for older versions.

A serial column has a sequence that is owned by the column and a DEFAULT value that gets the net sequence value.

If you try to change that column into an identity column, you’ll get an error that there is already a default value for the column.

Now you must have dropped the default value, but not the sequence that belongs to the serial column. Then when you converted the column into an identity column, a second sequence owned by the column was created.

Now when you try to insert a row, PostgreSQL tries to find and use the sequence owned by the column, but there are two, hence the error message.

I’d argue that this is a bug in PostgreSQL: in my opinion, it should either have repurposed the existing sequence for the identity column or given you an error that there is already a sequence owned by the column, and you should drop it. I’ll try to get this bug fixed.

Meanwhile, you should manually drop the sequence left behind from the serial column.
Run the following query:

SELECT d.objid::regclass
FROM pg_depend AS d
   JOIN pg_attribute AS a ON d.refobjid = a.attrelid AND
                             d.refobjsubid = a.attnum
WHERE d.classid = 'pg_class'::regclass
  AND d.refclassid = 'pg_class'::regclass
  AND d.deptype <> 'i'
  AND a.attname = 'patientid'
  AND d.refobjid = 'patient'::regclass;

That should give you the name of the sequence left behind from the serial column. Drop it, and the identity column should behave as desired.

Я устанавливаю столбец идентификаторов в существующие столбцы таблицы Patient.
Здесь я хотел бы использовать ВСЕГДА В КАЧЕСТВЕ ИДЕНТИЧНОСТИ .

Поэтому я установил столбец идентификаторов, используя следующую инструкцию (ранее это было serial):

ALTER TABLE Patient ALTER PatientId
   ADD GENERATED ALWAYS AS IDENTITY (START WITH 1);

Для существующей таблицы пациентов у меня всего 5 записей. (patientId с 1 по 5)
Когда я вставляю новую запись после установки идентификатора, она выдаст ошибку вроде:

more than one owned sequence found

Даже после сброса идентификационной колонки я все равно получаю ту же ошибку.

ALTER TABLE Patient ALTER COLUMN PatientId RESTART WITH 6;

Дайте мне знать, если у вас есть какие-либо решения.

2 ответа

Лучший ответ

Обновление : эта ошибка была исправлена в PostgreSQL версии 12 с помощью commit 19781729f78.
Остальная часть ответа актуальна для более старых версий.

Столбец serial имеет последовательность, которой владеет столбец, и значение DEFAULT, которое получает значение чистой последовательности.

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

Теперь вы должны удалить значение по умолчанию, но не последовательность, которая принадлежит столбцу serial. Затем, когда вы преобразовали столбец в столбец идентификаторов, была создана вторая последовательность, принадлежащая столбцу.

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

Я бы сказал, что это ошибка в PostgreSQL: по моему мнению, он должен был либо переназначить существующую последовательность для столбца идентификаторов, либо дать вам ошибку, что последовательность уже принадлежит столбцу, и вы должны удалить ее. Я постараюсь исправить эту ошибку.

Тем временем вы должны вручную удалить оставленную последовательность из столбца serial. Запустите следующий запрос:

SELECT d.objid::regclass
FROM pg_depend AS d
   JOIN pg_attribute AS a ON d.refobjid = a.attrelid AND
                             d.refobjsubid = a.attnum
WHERE d.classid = 'pg_class'::regclass
  AND d.refclassid = 'pg_class'::regclass
  AND d.deptype <> 'i'
  AND a.attname = 'patientid'
  AND d.refobjid = 'patient'::regclass;

Это должно дать вам имя последовательности, оставленной после столбца serial. Отбросьте его, и столбец идентификаторов должен вести себя как нужно.


4

Laurenz Albe
5 Авг 2019 в 11:32

Это не ответ — извинения, но это позволяет мне наглядно показать сумасшедшее поведение, которое я (непреднамеренно) обнаружил сегодня утром …

enter image description here

Все, что мне нужно было сделать, это следующее:

alter TABLE db.generic_items alter column generic_item_id drop default;
alter TABLE db.generic_items alter column generic_item_id add generated by default as identity;

И теперь при написании сценария для таблицы SQL я получаю (сокращенно):

CREATE TABLE db.generic_items
(
    generic_item_id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    generic_item_id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    generic_item_name character varying(50) COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT pk_generic_items PRIMARY KEY (generic_item_id),
)

Я благодарен Лоренцу Альбе за опубликованный выше ответ ! Как он объясняет, просто удалите последовательность, которая использовалась для серийного значения по умолчанию, и это сумасшествие исчезнет, и таблица снова будет выглядеть нормально.


0

Wellspring
1 Окт 2019 в 14:40

Обновлять: Эта ошибка была исправлена ​​в PostgreSQL v12 с фиксацией 19781729f78.
Остальная часть ответа актуальна для более старых версий.

Столбец serial имеет последовательность, которой владеет столбец, и значение DEFAULT, которое получает чистое значение последовательности.

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

Теперь вы, должно быть, отбросили значение по умолчанию, но не последовательность, принадлежащую столбцу serial. Затем, когда вы преобразовали столбец в столбец идентификаторов, была создана вторая последовательность, принадлежащая столбцу.

Теперь, когда вы пытаетесь вставить строку, PostgreSQL пытается найти и использовать последовательность в, принадлежащую столбцу, но их две, отсюда и сообщение об ошибке.

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

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

SELECT d.objid::regclass
FROM pg_depend AS d
   JOIN pg_attribute AS a ON d.refobjid = a.attrelid AND
                             d.refobjsubid = a.attnum
WHERE d.classid = 'pg_class'::regclass
  AND d.refclassid = 'pg_class'::regclass
  AND d.deptype <> 'i'
  AND a.attname = 'patientid'
  AND d.refobjid = 'patient'::regclass;

Это должно дать вам название последовательности, оставшейся после столбца serial. Отбросьте его, и столбец идентификаторов должен вести себя так, как хотелось бы.

do --check seq not in sync
$$
declare
 _r record;
 _i bigint;
 _m bigint;
begin
  for _r in (
    Select
      DISTINCT(constraint_column_usage.table_name) as tablename,
      constraint_column_usage.column_name as idname,
      replace(replace(columns.column_default,'''::regclass)',''),'nextval(''','') as seqname,
            columns.table_schema as schamename
      from information_schema.constraint_column_usage, information_schema.columns
      where constraint_column_usage.table_schema ='public' AND
      columns.table_schema = 'public' AND columns.table_name=constraint_column_usage.table_name
      AND constraint_column_usage.column_name = columns.column_name
      AND columns.column_default is not null
   ) loop
    execute format('select last_value from %I.%s',_r.schamename,_r.seqname) into _i;
    execute format('select max(%I) from %I.%I',_r.idname,_r.schamename,_r.tablename) into _m;
    if coalesce(_m,0) > _i then
      raise info '%',concat('changed: ',_r.tablename||'_Id_seq',' from:',_i,' to:',_m+1);
      execute format('alter sequence %I.%s restart with %s',_r.schamename,_r.seqname,_m+1);
    end if;
  end loop;

end;
$$
;

Recommend Projects

  • React photo

    React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo

    Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo

    Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo

    TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo

    Django

    The Web framework for perfectionists with deadlines.

  • Laravel photo

    Laravel

    A PHP framework for web artisans

  • D3 photo

    D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Visualization

    Some thing interesting about visualization, use data art

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo

    Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo

    Microsoft

    Open source projects and samples from Microsoft.

  • Google photo

    Google

    Google ❤️ Open Source for everyone.

  • Alibaba photo

    Alibaba

    Alibaba Open Source for everyone

  • D3 photo

    D3

    Data-Driven Documents codes.

  • Tencent photo

    Tencent

    China tencent open source team.

FlyWay + Spring Boot 2.x for vendor specific scripts error: found more than one migration with version 1.x

RichardK :

I’m trying to configure FlyWay to work with two vendors — one (H2) is for local environment, and another one (Mysql) is for ci.

Here’s my scripts patch:

patch

My FlyWay bean configuration:

@Bean(initMethod = "migrate")
    Flyway flyway() {
        Flyway flyway = Flyway
                .configure()
                .dataSource(dataSource(dataSourceProperties()))
                .locations("classpath:db/migration/MySQL", "classpath:db/migration/H2")
                .load();
        return flyway;
    }

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("spring.datasource")
    public HikariDataSource dataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().type(HikariDataSource.class)
                .build();
    }

And my application.yml configuration:

spring:
  main:
    allow-bean-definition-overriding: true
  datasource:
    driverClassName: com.mysql.cj.jdbc.Driver
    jdbc-url: jdbc:mysql://localhost:3306/messages
    username: username
    password: password

What I try to achieve is to make flyway run database vendor specific scripts, depending on which database is set in datasource. Here’s what I get:

Caused by: org.flywaydb.core.api.FlywayException: Found more than one migration with version 1.1
Offenders:
-> C:Projectsmy-projectoutproductionresourcesdbspecificMySQLV1_1__Create_table_message.sql (SQL)
-> C:Projectsmy-projectoutproductionresourcesdbspecificH2V1_1__Create_table_message.sql (SQL)

I’ve already tried to use lowercase vendor names (db/migration/mysql …) and use db/specific/ instead of db/migration. Nothing worked for me.

Mark Rotteveel :

The problem is your use of:

.locations("classpath:db/migration/MySQL", "classpath:db/migration/H2")

This will add both migrations to the runtime path. This is what causes the issue, because this configuration instructs flyway to always use the scripts from both locations, instead of only using the H2-scripts for H2 and the MySQL scripts for MySQL.

Instead, you should only add the specific path for the active driver on the path.

Something like

String driverVendor = ..; // something to decide h2 or mysql
Flyway flyway = Flyway
        .configure()
        .locations("classpath:db/migration/" + driverVendor)

You may need to lowercase the folder names, that is H2 to h2 and MySQL to mysql for this to work.

Alternatively, consider using Spring Boots Flyway auto-configuration instead of coding the Flyway configuration in code. This allows you to define the path in the application config as:

spring.flyway.locations=classpath:db/migration/{vendor}

Where {vendor} will be automatically populated with the vendor name of the driver used to connect.

See also Execute Flyway Database Migrations on Startup

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at2020-03-10

Related

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Pick a username
Email Address
Password

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account

basis data / Problem Solved

24 Mar 2022 ahhandoyoLeave a comment

Identity columns don’t work if they own more than one sequence. you can remove more sequence.

You can remove by code:

ALTER SEQUENCE name_of_sequence OWNED BY NONE;

Leave a Reply

Enter your comment here…

Fill in your details below or click an icon to log in:

Gravatar

Email (required) (Address never made public)

Name (required)

Website

WordPress.com Logo


You are commenting using your WordPress.com account.
( Log Out / 
Change )

Facebook photo


You are commenting using your Facebook account.
( Log Out / 
Change )

Cancel

Connecting to %s

Notify me of new comments via email.

Notify me of new posts via email.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

do --check seq not in sync
$$
declare
 _r record;
 _i bigint;
 _m bigint;
begin
  for _r in (
    Select
      DISTINCT(constraint_column_usage.table_name) as tablename,
      constraint_column_usage.column_name as idname,
      replace(replace(columns.column_default,'''::regclass)',''),'nextval(''','') as seqname,
            columns.table_schema as schamename
      from information_schema.constraint_column_usage, information_schema.columns
      where constraint_column_usage.table_schema ='public' AND
      columns.table_schema = 'public' AND columns.table_name=constraint_column_usage.table_name
      AND constraint_column_usage.column_name = columns.column_name
      AND columns.column_default is not null
   ) loop
    execute format('select last_value from %I.%s',_r.schamename,_r.seqname) into _i;
    execute format('select max(%I) from %I.%I',_r.idname,_r.schamename,_r.tablename) into _m;
    if coalesce(_m,0) > _i then
      raise info '%',concat('changed: ',_r.tablename||'_Id_seq',' from:',_i,' to:',_m+1);
      execute format('alter sequence %I.%s restart with %s',_r.schamename,_r.seqname,_m+1);
    end if;
  end loop;

end;
$$
;

  • Ошибка moonlight не найден trinus vr
  • Ошибка miswiring check wiring then pwr on kenwood
  • Ошибка missing operating system на ноутбуке
  • Ошибка missing operating system на компе
  • Ошибка missing operating system windows 10