1- import json
2- import psycopg2
3- from typing import List
1+ from sqlalchemy import Engine , create_engine
42
5- from metis .writer .writer import DQResultWriter
6- from metis .utils .result import DQResult
3+ from metis .writer .database_writer import DatabaseWriter
74
8- class PostgresWriter (DQResultWriter ):
9- def __init__ (self , writer_config ) -> None :
5+
6+ class PostgresWriter (DatabaseWriter ):
7+ def create_engine (self , writer_config ) -> Engine :
108 required_keys = ("db_user" , "db_pass" , "db_name" , "db_host" , "db_port" )
119 if not all (k in writer_config for k in required_keys ):
12- raise ValueError ("Postgres writer config must include 'db_user', 'db_pass', 'db_name', 'db_host', and 'db_port' fields." )
13-
14- self .table_name = writer_config .get ("table_name" )
15- self .DB_USER = writer_config .get ("db_user" )
16- self .DB_PASS = writer_config .get ("db_pass" )
17- self .DB_NAME = writer_config .get ("db_name" )
18- self .DB_HOST = writer_config .get ("db_host" )
19- self .DB_PORT = writer_config .get ("db_port" )
20-
21- conn = self .connect ()
22- self .create_db_schema (conn )
23- conn .close ()
10+ raise ValueError (
11+ "Postgres writer config must include 'db_user', 'db_pass', 'db_name', 'db_host', and 'db_port' fields."
12+ )
2413
25- def connect (self ):
26- conn = psycopg2 .connect (
27- dbname = self .DB_NAME ,
28- user = self .DB_USER ,
29- password = self .DB_PASS ,
30- host = self .DB_HOST ,
31- port = self .DB_PORT
14+ return create_engine (
15+ f"postgresql://{ writer_config ['db_user' ]} :{ writer_config ['db_pass' ]} @{ writer_config ['db_host' ]} :{ writer_config ['db_port' ]} /{ writer_config ['db_name' ]} " ,
16+ echo = True ,
3217 )
33- return conn
34-
35- def create_db_schema (self , conn ):
36- query = f"""
37- CREATE TABLE IF NOT EXISTS { self .table_name } (
38- id SERIAL PRIMARY KEY,
39- mes_time TIMESTAMP WITH TIME ZONE NOT NULL,
40- dq_value DOUBLE PRECISION NOT NULL,
41- dq_dimension TEXT NOT NULL,
42- dq_metric TEXT NOT NULL,
43- column_name JSONB,
44- row_index INTEGER,
45- dq_annotations JSONB,
46- dataset TEXT,
47- table_name TEXT
48- );
49- """
50- try :
51- cursor = conn .cursor ()
52- cursor .execute (query = query )
53- conn .commit ()
54- cursor .close ()
55- except Exception as e :
56- print (f'Error when saving or connecting to DB: { e } ' )
57-
58- def write (self , results : List [DQResult ]) -> None :
59- conn = self .connect ()
60- cur = conn .cursor ()
61-
62- for result in results :
63- print (f"Writing result: { result .as_json ()} " )
64- cur .execute (f'''
65- INSERT INTO { self .table_name } (mes_time, dq_value, dq_dimension, dq_metric, column_name, row_index, dq_annotations, dataset, table_name)
66- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
67- ''' , (
68- result .mesTime .to_pydatetime (),
69- result .DQvalue ,
70- result .DQdimension ,
71- result .DQmetric ,
72- json .dumps (result .columnNames ),
73- result .rowIndex ,
74- json .dumps (result .DQannotations ),
75- result .dataset ,
76- result .tableName
77- ))
78-
79- conn .commit ()
80- conn .close ()
0 commit comments