1+ # Copyright 2022-2023 The FormS Authors.
2+ #
3+ # Licensed under the Apache License, Version 2.0 (the "License");
4+ # you may not use this file except in compliance with the License.
5+ # You may obtain a copy of the License at
6+ #
7+ # http://www.apache.org/licenses/LICENSE-2.0
8+ #
9+ # Unless required by applicable law or agreed to in writing, software
10+ # distributed under the License is distributed on an "AS IS" BASIS,
11+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ # See the License for the specific language governing permissions and
13+ # limitations under the License.
14+
15+ import os
16+ import time
17+ import docker
18+ import pandas as pd
19+ import psycopg2
20+ from psycopg2 import Error
21+ from sqlalchemy import create_engine
22+ from docker .errors import DockerException
23+
24+ def wait_for_postgres (host , port , user , password , dbname , timeout = 15 ):
25+ start_time = time .time ()
26+ while time .time () - start_time < timeout :
27+ try :
28+ conn = psycopg2 .connect (dbname = dbname , user = user , password = password , host = host , port = port )
29+ conn .close ()
30+ return True
31+ except Error :
32+ time .sleep (1 )
33+ raise Exception ("PostgreSQL did not start within the given timeout" )
34+
35+
36+ def setup_postgres ():
37+ docker_client = docker .from_env ()
38+ host = "localhost"
39+ port = "5432"
40+ postgres_user = "dt"
41+ password = "1234"
42+ dbname = "forms_db"
43+ test_table = "test_table"
44+
45+ # Start the PostgreSQL container
46+ try :
47+ container = docker_client .containers .run (
48+ "postgres:13" ,
49+ environment = {
50+ "POSTGRES_USER" : postgres_user ,
51+ "POSTGRES_PASSWORD" : password ,
52+ "POSTGRES_DB" : dbname ,
53+ },
54+ ports = {"5432/tcp" : int (port )},
55+ detach = True ,
56+ )
57+ except DockerException as e :
58+ raise Exception (f"Failed to start PostgreSQL container: { e } " )
59+
60+ try :
61+ # Wait for the PostgreSQL service to be ready
62+ wait_for_postgres (host = host , port = port , user = postgres_user , password = password , dbname = dbname )
63+
64+ # Set the environment variables for the database connection
65+ os .environ ["POSTGRES_USER" ] = postgres_user
66+ os .environ ["POSTGRES_PASSWORD" ] = password
67+ os .environ ["POSTGRES_DB" ] = dbname
68+ os .environ ["POSTGRES_HOST" ] = host
69+ os .environ ["POSTGRES_PORT" ] = port
70+
71+ # Load a DataFrame into the database
72+ engine = create_engine (f"postgresql://{ postgres_user } :{ password } @{ host } :{ port } /{ dbname } " )
73+ df = pd .DataFrame ({"a" : [1 , 2 , 3 , 4 ], "b" : [2 , 2 , 2 , 2 ], "c" : [2 , 3 , 4 , 5 ], "d" : [3 , 2 , 2 , 3 ]})
74+ df .to_sql (test_table , engine , if_exists = "replace" , index = False )
75+
76+ os .environ ["POSTGRES_TEST_TABLE" ] = test_table
77+ os .environ ["POSTGRES_PRIMARY_KEY" ] = "a"
78+ os .environ ["POSTGRES_ORDER_KEY" ] = "a"
79+
80+ yield
81+
82+ finally :
83+ # Tear down the PostgreSQL container
84+ container .stop ()
85+ container .remove ()
0 commit comments