File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -3554,6 +3554,11 @@ def insert_all(
35543554 if hash_id_columns and hash_id is None :
35553555 hash_id = "id"
35563556
3557+ if upsert and not pk and not hash_id and self .exists ():
3558+ existing_pks = [column .name for column in self .columns if column .is_pk ]
3559+ if existing_pks :
3560+ pk = existing_pks [0 ] if len (existing_pks ) == 1 else tuple (existing_pks )
3561+
35573562 if upsert and (not pk and not hash_id ):
35583563 raise PrimaryKeyRequired ("upsert() requires a pk" )
35593564
Original file line number Diff line number Diff line change @@ -49,6 +49,53 @@ def test_upsert_error_if_no_pk(fresh_db):
4949 table .upsert ({"id" : 1 , "name" : "Cleo" })
5050
5151
52+ def test_upsert_error_if_existing_table_has_no_pk (fresh_db ):
53+ table = fresh_db .create_table ("table" , {"id" : int , "name" : str })
54+ with pytest .raises (PrimaryKeyRequired ):
55+ table .upsert ({"id" : 1 , "name" : "Cleo" })
56+
57+
58+ @pytest .mark .parametrize ("use_old_upsert" , (False , True ))
59+ def test_upsert_uses_compound_pk_from_existing_table (use_old_upsert ):
60+ # https://github.com/simonw/sqlite-utils/issues/629
61+ db = Database (memory = True , use_old_upsert = use_old_upsert )
62+ db .execute ("""
63+ create table summary (
64+ Source text,
65+ Object text,
66+ Category text,
67+ Count integer,
68+ primary key (Source, Object, Category)
69+ )
70+ """ )
71+ table = db ["summary" ]
72+ table .upsert (
73+ {
74+ "Source" : "Client A" ,
75+ "Object" : "Accounts" ,
76+ "Category" : "All" ,
77+ "Count" : 3 ,
78+ }
79+ )
80+ assert table .last_pk == ("Client A" , "Accounts" , "All" )
81+ table .upsert (
82+ {
83+ "Source" : "Client A" ,
84+ "Object" : "Accounts" ,
85+ "Category" : "All" ,
86+ "Count" : 4 ,
87+ }
88+ )
89+ assert list (table .rows ) == [
90+ {
91+ "Source" : "Client A" ,
92+ "Object" : "Accounts" ,
93+ "Category" : "All" ,
94+ "Count" : 4 ,
95+ }
96+ ]
97+
98+
5299def test_upsert_with_hash_id (fresh_db ):
53100 table = fresh_db ["table" ]
54101 table .upsert ({"foo" : "bar" }, hash_id = "pk" )
You can’t perform that action at this time.
0 commit comments