1010import requests
1111import urllib3
1212from dotenv import load_dotenv
13- import arcpy
13+ import psycopg2
1414from geopycat import settings
1515from geopycat import utils
1616
@@ -101,8 +101,9 @@ def __get_token(self) -> object:
101101 return session
102102
103103 def db_connect (self ) -> object :
104- """Connect to geocat DB and returns an arcpy connection object"""
104+ """Connect to geocat DB and returns a psycopg2 connection object"""
105105
106+ # Access database credentials from env variable if exists
106107 db_username = os .getenv ('DB_USERNAME' )
107108 db_password = os .getenv ('DB_PASSWORD' )
108109
@@ -112,9 +113,11 @@ def db_connect(self) -> object:
112113
113114 _env = [k for k , v in settings .ENV .items () if v == self .env ][0 ]
114115
115- connection_string = f"DATABASE_PLATFORM=POSTGRESQL;DATABASE={ _env } ;DBCLIENT=postgresql;DB_CONNECTION_PROPERTIES=database-lb.geocat.swisstopo.cloud;USER={ db_username } ;PASSWORD={ db_password } ;VERSION=sde.DEFAULT"
116-
117- connection = arcpy .ArcSDESQLExecute (connection_string )
116+ connection = psycopg2 .connect (
117+ host = "database-lb.geocat.swisstopo.cloud" ,
118+ database = f"geocat-{ _env } " ,
119+ user = db_username ,
120+ password = db_password )
118121
119122 return connection
120123
@@ -508,6 +511,8 @@ def backup_metadata(self, uuids: list, backup_dir: str = None, with_related: boo
508511 print (f"{ utils .warningred ('The following Metadata could not be backup : ' ) + uuid } " )
509512 continue
510513
514+ uuid = uuid .replace (":" , "_" ).replace ("/" , "_" ).replace ("\\ " , "_" ).replace ("'" , "_" ).replace ('"' , "_" )
515+
511516 with open (os .path .join (backup_dir , f"{ uuid } .zip" ), "wb" ) as output :
512517 output .write (response .content )
513518
@@ -556,6 +561,8 @@ def backup_metadata_xml(self, uuids: list, backup_dir: str = None):
556561 print (f"{ utils .warningred ('The following Metadata could not be backup : ' ) + uuid } " )
557562 continue
558563
564+ uuid = uuid .replace (":" , "_" ).replace ("/" , "_" ).replace ("\\ " , "_" ).replace ("'" , "_" ).replace ('"' , "_" )
565+
559566 with open (os .path .join (backup_dir , f"{ uuid } .xml" ), "wb" ) as output :
560567 output .write (response .content )
561568
@@ -744,58 +751,52 @@ def search_and_replace(self, search: str, replace: str, escape_wildcard: bool =
744751
745752 try :
746753 connection = self .db_connect ()
754+ with connection .cursor () as cursor :
747755
748- query = f"""
749- SELECT uuid FROM public.metadata
750- WHERE (istemplate = 'n' OR istemplate = 'y')
751- AND data LIKE '%{ search_sql } %'
752- """
756+ cursor .execute ("SELECT uuid FROM public.metadata where (istemplate='n' OR istemplate='y')" \
757+ f"AND data like '%{ search_sql } %'" )
753758
754- result = connection .execute (query )
759+ for row in cursor :
760+ metadata_uuids .append (row [0 ])
755761
756- for row in result :
757- metadata_uuids . append ( row [ 0 ] )
762+ except ( Exception , psycopg2 . Error ) as error :
763+ print ( "Error while fetching data from PostgreSQL" , error )
758764
759- except arcpy .ExecuteError :
760- msgs = arcpy .GetMessages (2 )
761- print (f"Error while fetching data from the geodatabase: { msgs } " )
762- except Exception as error :
763- print (f"Unexpected error: { error } " )
765+ finally :
766+ if connection :
767+ connection .close ()
764768
765769 headers = {"accept" : "application/json" , "Content-Type" : "application/json" }
766770
767771 if len (metadata_uuids ) == 0 :
768- print (f"Warning: ' { search } ' not found in any metadata" )
772+ print (utils . warningred ( f" { search } not found in any metadata") )
769773 return
770774
771775 for uuid in metadata_uuids :
776+
772777 params = {
773778 "search" : search ,
774779 "replace" : replace ,
775780 "uuids" : [uuid ],
776781 "updateDateStamp" : False
777782 }
778783
779- response = self .session .post (
780- self .env + "/geonetwork/srv/api/processes/db/search-and-replace" ,
781- params = params ,
782- headers = headers
783- )
784+ response = self .session .post (self .env + "/geonetwork/srv/api/processes/db/search-and-replace" ,
785+ params = params , headers = headers )
784786
785- if hasattr (response , 'ok' ) and response . ok :
786- print (f"Metadata { uuid } : ' { search } ' successfully replaced by ' { replace } '" )
787+ if utils . process_ok (response ) :
788+ print (utils . okgreen ( f"Metadata { uuid } : { search } successfully replaced by { replace } " ) )
787789 else :
788- print (f"Metadata { uuid } : '{ search } ' unsuccessfully replaced by '{ replace } '" )
789-
790+ print (utils .warningred (f"Metadata { uuid } : { search } unsuccessfully replaced by { replace } " ))
790791
791792 def search_db (self , search : str , escape_wildcard : bool = True ) -> list :
792793 """
793- Performs search at the DB level using arcpy.ArcSDESQLExecute.
794- Returns a list of metadata UUIDs where the search input was found.
794+ Performs search at the DB level. Returns list of metadata UUID where search
795+ input was found.
795796
796797 Parameters:
797- search (str): Value to search for.
798- escape_wildcard (bool): If True, "%" wildcards are escaped as "\%".
798+ search (str): value to search for
799+ escape_wildcard (bool): if True, "%" wildcard are escaped "\%"
799800 """
800801
801802 if not self .check_admin ():
@@ -809,30 +810,22 @@ def search_db(self, search: str, escape_wildcard: bool = True) -> list:
809810 search_sql = search
810811
811812 try :
812- # Establish the database connection
813813 connection = self .db_connect ()
814+ with connection .cursor () as cursor :
814815
815- # Build the SQL query
816- query = f"""
817- SELECT uuid FROM public.metadata
818- WHERE (istemplate = 'n' OR istemplate = 'y')
819- AND data LIKE '%{ search_sql } %'
820- """
816+ cursor .execute ("SELECT uuid FROM public.metadata where (istemplate='n' OR istemplate='y')" \
817+ f"AND data like '%{ search_sql } %'" )
821818
822- # Execute the query using arcpy.ArcSDESQLExecute
823- result = connection . execute ( query )
819+ for row in cursor :
820+ metadata_uuids . append ( row [ 0 ] )
824821
825- # Fetch the results
826- for row in result :
827- metadata_uuids .append (row [0 ])
828-
829- except arcpy .ExecuteError :
830- # Retrieve arcpy-specific error messages
831- msgs = arcpy .GetMessages (2 )
832- print (f"Error while fetching data from the geodatabase: { msgs } " )
833- except Exception as error :
834- print (f"Unexpected error: { error } " )
822+ except (Exception , psycopg2 .Error ) as error :
823+ print ("Error while fetching data from PostgreSQL" , error )
835824
825+ finally :
826+ if connection :
827+ connection .close ()
828+
836829 return metadata_uuids
837830
838831 def delete_metadata (self , uuid : str ) -> object :
0 commit comments