@@ -6476,38 +6476,45 @@ def duplicate_record(self, dataset: DataSet, children: bool) -> pd.DataFrame:
6476
6476
# This can be done using * syntax without knowing the schema of the table
6477
6477
# (other than primary key column). The trick is to create a temporary table
6478
6478
# using the "CREATE TABLE AS" syntax.
6479
- description = self . quote_value (
6479
+ description = (
6480
6480
f"{ lang .duplicate_prepend } "
6481
6481
f"{ dataset .get_description_for_pk (dataset .get_current_pk ())} "
6482
6482
)
6483
6483
table = self .quote_table (dataset .table )
6484
- tmp_table = self .quote_table (f"temp_{ dataset .table } " )
6485
6484
pk_column = self .quote_column (dataset .pk_column )
6485
+ current_pk = dataset .get_current (dataset .pk_column )
6486
6486
description_column = self .quote_column (dataset .description_column )
6487
+ columns = [
6488
+ self .quote_column (column ["name" ])
6489
+ for column in dataset .column_info
6490
+ if column ["name" ] != dataset .pk_column
6491
+ ]
6492
+ columns = ", " .join (columns )
6487
6493
pk = None # we will update this later...
6488
6494
6489
- # Create tmp table, update pk column in temp and insert into table
6490
- query = [
6491
- f"DROP TABLE IF EXISTS { tmp_table } ;" ,
6492
- (
6493
- f"CREATE TEMPORARY TABLE { tmp_table } AS SELECT * FROM { table } WHERE "
6494
- f"{ pk_column } ={ dataset .get_current (dataset .pk_column )} ;"
6495
- ),
6496
- (
6497
- f"UPDATE { tmp_table } SET { pk_column } = "
6498
- f"{ self .next_pk (dataset .table , dataset .pk_column )} ;"
6499
- ),
6500
- f"UPDATE { tmp_table } SET { description_column } = { description } " ,
6501
- f"INSERT INTO { table } SELECT * FROM { tmp_table } ;" ,
6502
- f"DROP TABLE IF EXISTS { tmp_table } ;" ,
6503
- ]
6504
- for q in query :
6505
- res = self .execute (q )
6506
- if res .attrs ["exception" ]:
6507
- return res
6508
- if pk is None and res .attrs ["lastrowid" ] is not None :
6509
- # Now we save the new pk
6510
- pk = res .attrs ["lastrowid" ]
6495
+ # Insert new row
6496
+ query = (
6497
+ f"INSERT INTO { table } ({ columns } ) "
6498
+ f"SELECT { columns } FROM { table } "
6499
+ f"WHERE { pk_column } = { current_pk } ;"
6500
+ )
6501
+ res = self .execute (query )
6502
+ if res .attrs ["exception" ]:
6503
+ return res
6504
+ if pk is None and res .attrs ["lastrowid" ] is not None :
6505
+ # Now we save the new pk
6506
+ pk = res .attrs ["lastrowid" ]
6507
+
6508
+ # Update the description
6509
+ query = (
6510
+ f"UPDATE { table } "
6511
+ f"SET { description_column } = ? "
6512
+ f"WHERE { pk_column } = { pk } ;"
6513
+ )
6514
+
6515
+ res = self .execute (query , [description ])
6516
+ if res .attrs ["exception" ]:
6517
+ return res
6511
6518
6512
6519
# create list of which children we have duplicated
6513
6520
child_duplicated = []
@@ -6521,31 +6528,34 @@ def duplicate_record(self, dataset: DataSet, children: bool) -> pd.DataFrame:
6521
6528
and (r .child_table not in child_duplicated )
6522
6529
):
6523
6530
child = self .quote_table (r .child_table )
6524
- tmp_child = self .quote_table (f"temp_{ r .child_table } " )
6525
6531
pk_column = self .quote_column (
6526
6532
dataset .frm [r .child_table ].pk_column
6527
6533
)
6528
6534
fk_column = self .quote_column (r .fk_column )
6529
-
6530
- # Update children's pk_columns to NULL and set correct parent
6531
- # PK value.
6532
- queries = [
6533
- f"DROP TABLE IF EXISTS { tmp_child } ;" ,
6534
- (
6535
- f"CREATE TEMPORARY TABLE { tmp_child } AS "
6536
- f"SELECT * FROM { child } WHERE { fk_column } ="
6537
- f"{ dataset .get_current (dataset .pk_column )} ;"
6538
- ),
6539
- # don't next_pk(), because child can be plural.
6540
- f"UPDATE { tmp_child } SET { pk_column } = NULL;" ,
6541
- f"UPDATE { tmp_child } SET { fk_column } = { pk } " ,
6542
- f"INSERT INTO { child } SELECT * FROM { tmp_child } ;" ,
6543
- f"DROP TABLE IF EXISTS { tmp_child } ;" ,
6535
+ columns = [
6536
+ self .quote_column (column ["name" ])
6537
+ for column in dataset .frm [r .child_table ].column_info
6538
+ if column ["name" ] != dataset .frm [r .child_table ].pk_column
6544
6539
]
6545
- for q in queries :
6546
- res = self .execute (q )
6547
- if res .attrs ["exception" ]:
6548
- return res
6540
+
6541
+ # use new pk on insert
6542
+ select_columns = [
6543
+ str (pk )
6544
+ if column == self .quote_column (r .fk_column )
6545
+ else column
6546
+ for column in columns
6547
+ ]
6548
+ columns = ", " .join (columns )
6549
+ select_columns = ", " .join (select_columns )
6550
+
6551
+ query = (
6552
+ f"INSERT INTO { child } ({ columns } ) "
6553
+ f"SELECT { select_columns } FROM { child } "
6554
+ f"WHERE { fk_column } = { current_pk } ;"
6555
+ )
6556
+ res = self .execute (query )
6557
+ if res .attrs ["exception" ]:
6558
+ return res
6549
6559
6550
6560
child_duplicated .append (r .child_table )
6551
6561
# If we made it here, we can return the pk. Since the pk was stored earlier,
0 commit comments