Skip to content

Commit b6346a5

Browse files
committed
Move updating sequence value to clean_up stage
1 parent 0fdfaec commit b6346a5

File tree

3 files changed

+27
-23
lines changed

3 files changed

+27
-23
lines changed

src/psycopack/_commands.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -476,20 +476,11 @@ def swap_pk_sequence_name(self, *, first_table: str, second_table: str) -> None:
476476
self.rename_sequence(seq_from=second_seq, seq_to=first_seq)
477477
self.rename_sequence(seq_from=temp_seq, seq_to=second_seq)
478478

479-
def transfer_pk_sequence_value(
480-
self, *, source_table: str, dest_table: str, convert_pk_to_bigint: bool
481-
) -> None:
479+
def transfer_pk_sequence_value(self, *, source_table: str, dest_table: str) -> None:
482480
source_seq = self.introspector.get_pk_sequence_name(table=source_table)
483481
dest_seq = self.introspector.get_pk_sequence_name(table=dest_table)
484482
value = self.introspector.get_pk_sequence_value(seq=source_seq)
485483

486-
if convert_pk_to_bigint and value < 0:
487-
# special case handling where negative PK values were used before bigint conversion
488-
value = 2**31 # reset to positive, specifically the first bigint value
489-
490-
# TODO: try to correctly restore a negative PK sequence value if we revert swap
491-
# while doing a bigint conversion
492-
493484
self.cur.execute(
494485
psycopg.sql.SQL("SELECT setval('{schema}.{sequence}', {value});")
495486
.format(
@@ -500,6 +491,27 @@ def transfer_pk_sequence_value(
500491
.as_string(self.conn)
501492
)
502493

494+
def update_pk_sequence_value(self, *, table: str) -> None:
495+
"""
496+
Update the sequence value if it was negative (for use in bigint conversions).
497+
"""
498+
seq = self.introspector.get_pk_sequence_name(table=table)
499+
value = self.introspector.get_pk_sequence_value(seq=seq)
500+
501+
if value < 0:
502+
# special case handling where negative PK values were used before bigint conversion
503+
value = 2**31 # reset to positive, specifically the first bigint value
504+
505+
self.cur.execute(
506+
psycopg.sql.SQL("SELECT setval('{schema}.{sequence}', {value});")
507+
.format(
508+
schema=psycopg.sql.Identifier(self.schema),
509+
sequence=psycopg.sql.Identifier(seq),
510+
value=psycopg.sql.SQL(str(value)),
511+
)
512+
.as_string(self.conn)
513+
)
514+
503515
def acquire_access_exclusive_lock(self, *, table: str) -> None:
504516
self.cur.execute(
505517
psycopg.sql.SQL("LOCK TABLE {schema}.{table} IN ACCESS EXCLUSIVE MODE;")

src/psycopack/_repack.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,6 @@ def swap(self) -> None:
403403
self.command.transfer_pk_sequence_value(
404404
source_table=self.table,
405405
dest_table=self.copy_table,
406-
convert_pk_to_bigint=self.convert_pk_to_bigint,
407406
)
408407
self.command.rename_table(
409408
table_from=self.table, table_to=self.repacked_name
@@ -461,7 +460,6 @@ def revert_swap(self) -> None:
461460
self.command.transfer_pk_sequence_value(
462461
source_table=self.table,
463462
dest_table=self.repacked_name,
464-
convert_pk_to_bigint=self.convert_pk_to_bigint,
465463
)
466464

467465
self.command.rename_table(table_from=self.table, table_to=self.copy_table)
@@ -507,6 +505,11 @@ def clean_up(self) -> None:
507505
)
508506
self.command.drop_function_if_exists(function=self.repacked_function)
509507

508+
if self.convert_pk_to_bigint and self.introspector.get_pk_sequence_name(
509+
table=self.table
510+
):
511+
self.command.update_pk_sequence_value(table=self.table)
512+
510513
for idx_sql in indexes:
511514
for index_data in indexes[idx_sql]:
512515
self.command.rename_index(

tests/test_repack.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
from typing import Tuple, Union
44
from unittest import mock
55

6-
from psycopg.errors import NumericValueOutOfRange
7-
86
import pytest
97

108
from psycopack import (
@@ -1399,15 +1397,6 @@ def test_when_table_has_negative_pk_values(
13991397
)
14001398

14011399

1402-
@pytest.mark.xfail(
1403-
raises=NumericValueOutOfRange,
1404-
reason="""
1405-
E psycopg.errors.NumericValueOutOfRange: integer out of range
1406-
E CONTEXT: SQL function "psycopack_repacked_6723301_fun" statement 1
1407-
E SQL statement "SELECT "public"."psycopack_repacked_6723301_fun"(NEW."id", NEW."id")"
1408-
E PL/pgSQL function psycopack_repacked_6723301_tgr() line 4 at PERFORM
1409-
""",
1410-
)
14111400
def test_with_writes_when_table_has_negative_pk_values(
14121401
connection: _psycopg.Connection,
14131402
) -> None:

0 commit comments

Comments
 (0)