@@ -2970,16 +2970,21 @@ def execute_script(self,script):
2970
2970
# --------------
2971
2971
try :
2972
2972
import psycopg2
2973
+ import psycopg2 .extras
2973
2974
except ModuleNotFoundError :
2974
2975
pass
2975
- class Postgre (SQLDriver ):
2976
+
2977
+ class Postgres (SQLDriver ):
2976
2978
def __init__ (self ,host ,user ,password ,database ,sql_script = None , sql_commands = None ):
2977
2979
self .host = host
2978
2980
self .user = user
2979
2981
self .password = password
2980
2982
self .database = database
2981
2983
self .con = self .connect ()
2982
2984
2985
+ query = "CREATE COLLATION nocase (provider = icu, locale = 'und-u-ks-level2');"
2986
+ self .execute (query )
2987
+
2983
2988
if sql_commands is not None :
2984
2989
# run SQL script if the database does not yet exist
2985
2990
logger .info (f'Executing sql commands passed in' )
@@ -3001,14 +3006,16 @@ def connect(self):
3001
3006
return con
3002
3007
3003
3008
def execute (self , query , values = None ):
3004
- cursor = self .con .cursor (dictionary = True )
3009
+ cursor = self .con .cursor (cursor_factory = psycopg2 . extras . RealDictCursor )
3005
3010
if values :
3006
3011
cursor .execute (query , values )
3007
3012
else :
3008
3013
cursor .execute (query )
3014
+ if len (cursor ) == 0 : return
3015
+ results = cursor .fetchall ()
3009
3016
3010
3017
res = []
3011
- for row in cursor :
3018
+ for row in results :
3012
3019
res .append (row )
3013
3020
3014
3021
lastrowid = cursor .lastrowid if cursor .lastrowid else None
@@ -3025,6 +3032,49 @@ def close(self):
3025
3032
# Only do cleanup if this is not an imported database
3026
3033
self .con .close ()
3027
3034
3035
+ def table_names (self ):
3036
+ query = "SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE';"
3037
+ #query = "SELECT tablename FROM pg_tables WHERE table_schema='public'"
3038
+ rows = self .execute (query )
3039
+ return [row ['table_name' ] for row in rows ]
3040
+
3041
+ def column_names (self ,table ):
3042
+ # Return a list of column names
3043
+ query = f"SELECT column_name FROM information_schema.columns WHERE table_name = '{ table } '"
3044
+ rows = self .execute (query )
3045
+ return [row ['column_name' ] for row in rows ]
3046
+ def pk_column (self ,table ):
3047
+ query = f"SELECT column_name FROM information_schema.table_constraints tc JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name WHERE tc.constraint_type = 'PRIMARY KEY' AND tc.table_name = '{ table } ' "
3048
+ cur = self .execute (query )
3049
+ row = cur .fetchone ()
3050
+ return row ['column_name' ] if row else None
3051
+ def relationships (self ):
3052
+ # Return a list of dicts {from_table,to_table,from_column,to_column,requery}
3053
+ tables = self .table_names ()
3054
+ relationships = []
3055
+ for from_table in tables :
3056
+ query = f"SELECT conname, conrelid::regclass, confrelid::regclass, confupdtype, "
3057
+ query += f"a1.attname AS column_name, a2.attname AS referenced_column_name "
3058
+ query += f"FROM pg_constraint "
3059
+ query += f"JOIN pg_attribute AS a1 ON conrelid = a1.attrelid AND a1.attnum = ANY(conkey) "
3060
+ query += f"JOIN pg_attribute AS a2 ON confrelid = a2.attrelid AND a2.attnum = ANY(confkey) "
3061
+ query += f"WHERE confrelid = '{ from_table } '::regclass AND contype = 'f'"
3062
+
3063
+ rows = self .execute (query , (from_table ,))
3064
+ for row in rows :
3065
+ dic = {}
3066
+ # Get the constraint information
3067
+ #constraint = self.constraint(row['conname'])
3068
+ if row ['conname' ] == 'c' :
3069
+ dic ['requery' ] = True
3070
+ else :
3071
+ dic ['requery' ] = False
3072
+ dic ['from_table' ] = row ['confrelid' ]
3073
+ dic ['to_table' ] = row ['conrelid' ]
3074
+ dic ['from_column' ] = row ['referenced_column_name' ]
3075
+ dic ['to_column' ] = row ['column_name' ]
3076
+ relationships .append (dic )
3077
+ return relationships
3028
3078
3029
3079
3030
3080
# ======================================================================================================================
0 commit comments