@@ -102,44 +102,43 @@ async def find_by_permalinks(self, permalinks: List[str]) -> Sequence[Entity]:
102102
103103 async def upsert_entity (self , entity : Entity ) -> Entity :
104104 """Insert or update entity using a hybrid approach.
105-
105+
106106 This method provides a cleaner alternative to the try/catch approach
107- for handling permalink and file_path conflicts. It first tries direct
107+ for handling permalink and file_path conflicts. It first tries direct
108108 insertion, then handles conflicts intelligently.
109-
109+
110110 Args:
111111 entity: The entity to insert or update
112-
112+
113113 Returns:
114114 The inserted or updated entity
115115 """
116116
117117 async with db .scoped_session (self .session_maker ) as session :
118118 # Set project_id if applicable and not already set
119119 self ._set_project_id_if_needed (entity )
120-
120+
121121 # Check for existing entity with same file_path first
122122 existing_by_path = await session .execute (
123123 select (Entity ).where (
124- Entity .file_path == entity .file_path ,
125- Entity .project_id == entity .project_id
124+ Entity .file_path == entity .file_path , Entity .project_id == entity .project_id
126125 )
127126 )
128127 existing_path_entity = existing_by_path .scalar_one_or_none ()
129-
128+
130129 if existing_path_entity :
131130 # Update existing entity with same file path
132131 for key , value in {
133- ' title' : entity .title ,
134- ' entity_type' : entity .entity_type ,
135- ' entity_metadata' : entity .entity_metadata ,
136- ' content_type' : entity .content_type ,
137- ' permalink' : entity .permalink ,
138- ' checksum' : entity .checksum ,
139- ' updated_at' : entity .updated_at ,
132+ " title" : entity .title ,
133+ " entity_type" : entity .entity_type ,
134+ " entity_metadata" : entity .entity_metadata ,
135+ " content_type" : entity .content_type ,
136+ " permalink" : entity .permalink ,
137+ " checksum" : entity .checksum ,
138+ " updated_at" : entity .updated_at ,
140139 }.items ():
141140 setattr (existing_path_entity , key , value )
142-
141+
143142 await session .flush ()
144143 # Return with relationships loaded
145144 query = (
@@ -150,15 +149,17 @@ async def upsert_entity(self, entity: Entity) -> Entity:
150149 result = await session .execute (query )
151150 found = result .scalar_one_or_none ()
152151 if not found : # pragma: no cover
153- raise RuntimeError (f"Failed to retrieve entity after update: { entity .file_path } " )
152+ raise RuntimeError (
153+ f"Failed to retrieve entity after update: { entity .file_path } "
154+ )
154155 return found
155-
156+
156157 # No existing entity with same file_path, try insert
157158 try :
158159 # Simple insert for new entity
159160 session .add (entity )
160161 await session .flush ()
161-
162+
162163 # Return with relationships loaded
163164 query = (
164165 select (Entity )
@@ -168,36 +169,37 @@ async def upsert_entity(self, entity: Entity) -> Entity:
168169 result = await session .execute (query )
169170 found = result .scalar_one_or_none ()
170171 if not found : # pragma: no cover
171- raise RuntimeError (f"Failed to retrieve entity after insert: { entity .file_path } " )
172+ raise RuntimeError (
173+ f"Failed to retrieve entity after insert: { entity .file_path } "
174+ )
172175 return found
173-
176+
174177 except IntegrityError :
175178 # Could be either file_path or permalink conflict
176179 await session .rollback ()
177-
180+
178181 # Check if it's a file_path conflict (race condition)
179182 existing_by_path_check = await session .execute (
180183 select (Entity ).where (
181- Entity .file_path == entity .file_path ,
182- Entity .project_id == entity .project_id
184+ Entity .file_path == entity .file_path , Entity .project_id == entity .project_id
183185 )
184186 )
185187 race_condition_entity = existing_by_path_check .scalar_one_or_none ()
186-
188+
187189 if race_condition_entity :
188190 # Race condition: file_path conflict detected after our initial check
189191 # Update the existing entity instead
190192 for key , value in {
191- ' title' : entity .title ,
192- ' entity_type' : entity .entity_type ,
193- ' entity_metadata' : entity .entity_metadata ,
194- ' content_type' : entity .content_type ,
195- ' permalink' : entity .permalink ,
196- ' checksum' : entity .checksum ,
197- ' updated_at' : entity .updated_at ,
193+ " title" : entity .title ,
194+ " entity_type" : entity .entity_type ,
195+ " entity_metadata" : entity .entity_metadata ,
196+ " content_type" : entity .content_type ,
197+ " permalink" : entity .permalink ,
198+ " checksum" : entity .checksum ,
199+ " updated_at" : entity .updated_at ,
198200 }.items ():
199201 setattr (race_condition_entity , key , value )
200-
202+
201203 await session .flush ()
202204 # Return the updated entity with relationships loaded
203205 query = (
@@ -208,7 +210,9 @@ async def upsert_entity(self, entity: Entity) -> Entity:
208210 result = await session .execute (query )
209211 found = result .scalar_one_or_none ()
210212 if not found : # pragma: no cover
211- raise RuntimeError (f"Failed to retrieve entity after race condition update: { entity .file_path } " )
213+ raise RuntimeError (
214+ f"Failed to retrieve entity after race condition update: { entity .file_path } "
215+ )
212216 return found
213217 else :
214218 # Must be permalink conflict - generate unique permalink
@@ -218,26 +222,25 @@ async def _handle_permalink_conflict(self, entity: Entity, session: AsyncSession
218222 """Handle permalink conflicts by generating a unique permalink."""
219223 base_permalink = entity .permalink
220224 suffix = 1
221-
225+
222226 # Find a unique permalink
223227 while True :
224228 test_permalink = f"{ base_permalink } -{ suffix } "
225229 existing = await session .execute (
226230 select (Entity ).where (
227- Entity .permalink == test_permalink ,
228- Entity .project_id == entity .project_id
231+ Entity .permalink == test_permalink , Entity .project_id == entity .project_id
229232 )
230233 )
231234 if existing .scalar_one_or_none () is None :
232235 # Found unique permalink
233236 entity .permalink = test_permalink
234237 break
235238 suffix += 1
236-
239+
237240 # Insert with unique permalink (no conflict possible now)
238241 session .add (entity )
239242 await session .flush ()
240-
243+
241244 # Return the inserted entity with relationships loaded
242245 query = (
243246 select (Entity )
0 commit comments