1818import  os 
1919
2020# [START cloud_sql_connector_postgres_psycopg] 
21+ from  typing  import  Union 
22+ 
23+ import  sqlalchemy 
2124
2225from  google .cloud .sql .connector  import  Connector 
2326from  google .cloud .sql .connector  import  DefaultResolver 
27+ from  google .cloud .sql .connector  import  DnsResolver 
28+ 
29+ 
30+ def  create_sqlalchemy_engine (
31+     instance_connection_name : str ,
32+     user : str ,
33+     password : str ,
34+     db : str ,
35+     ip_type : str  =  "public" ,
36+     refresh_strategy : str  =  "background" ,
37+     resolver : Union [type [DefaultResolver ], type [DnsResolver ]] =  DefaultResolver ,
38+ ) ->  tuple [sqlalchemy .engine .Engine , Connector ]:
39+     """Creates a connection pool for a Cloud SQL instance and returns the pool 
40+     and the connector. Callers are responsible for closing the pool and the 
41+     connector. 
42+ 
43+     A sample invocation looks like: 
44+ 
45+         engine, connector = create_sqlalchemy_engine( 
46+             inst_conn_name, 
47+             user, 
48+             password, 
49+             db, 
50+         ) 
51+         with engine.connect() as conn: 
52+             time = conn.execute(sqlalchemy.text("SELECT NOW()")).fetchone() 
53+             conn.commit() 
54+             curr_time = time[0] 
55+             # do something with query result 
56+             connector.close() 
57+ 
58+     Args: 
59+         instance_connection_name (str): 
60+             The instance connection name specifies the instance relative to the 
61+             project and region. For example: "my-project:my-region:my-instance" 
62+         user (str): 
63+             The database user name, e.g., root 
64+         password (str): 
65+             The database user's password, e.g., secret-password 
66+         db (str): 
67+             The name of the database, e.g., mydb 
68+         ip_type (str): 
69+             The IP type of the Cloud SQL instance to connect to. Can be one 
70+             of "public", "private", or "psc". 
71+         refresh_strategy (Optional[str]): 
72+             Refresh strategy for the Cloud SQL Connector. Can be one of "lazy" 
73+             or "background". For serverless environments use "lazy" to avoid 
74+             errors resulting from CPU being throttled. 
75+         resolver (Optional[google.cloud.sql.connector.DefaultResolver]): 
76+             Resolver class for resolving instance connection name. Use 
77+             google.cloud.sql.connector.DnsResolver when resolving DNS domain 
78+             names or google.cloud.sql.connector.DefaultResolver for regular 
79+             instance connection names ("my-project:my-region:my-instance"). 
80+     """ 
81+     connector  =  Connector (refresh_strategy = refresh_strategy , resolver = resolver )
82+ 
83+     # create SQLAlchemy connection pool 
84+     engine  =  sqlalchemy .create_engine (
85+         "postgresql+psycopg://" ,
86+         creator = lambda : connector .connect (
87+             instance_connection_name ,
88+             "psycopg" ,
89+             user = user ,
90+             password = password ,
91+             db = db ,
92+             local_socket_path = "/tmp/conn" ,
93+             ip_type = ip_type ,  # can be "public", "private" or "psc" 
94+             autocommit = True ,
95+         ),
96+     )
97+     return  engine , connector 
2498
25- from  sqlalchemy .dialects .postgresql .base  import  PGDialect 
26- PGDialect ._get_server_version_info  =  lambda  * args : (9 , 2 )
2799
28100# [END cloud_sql_connector_postgres_psycopg] 
29101
@@ -36,25 +108,12 @@ def test_psycopg_connection() -> None:
36108    db  =  os .environ ["POSTGRES_DB" ]
37109    ip_type  =  os .environ .get ("IP_TYPE" , "public" )
38110
39-     connector  =  Connector (refresh_strategy = "background" , resolver = DefaultResolver )
40- 
41-     pool  =  connector .connect (
42-         inst_conn_name ,
43-         "psycopg" ,
44-         user = user ,
45-         password = password ,
46-         db = db ,
47-         ip_type = ip_type ,  # can be "public", "private" or "psc" 
111+     engine , connector  =  create_sqlalchemy_engine (
112+         inst_conn_name , user , password , db , ip_type 
48113    )
49- 
50-     with  pool  as  conn :
51- 
52-         # Open a cursor to perform database operations 
53-         with  conn .cursor () as  cur :
54- 
55-             # Query the database and obtain data as Python objects. 
56-             cur .execute ("SELECT NOW()" )
57-             curr_time  =  cur .fetchone ()["now" ]
58-             assert  type (curr_time ) is  datetime 
59- 
60- 
114+     with  engine .connect () as  conn :
115+         time  =  conn .execute (sqlalchemy .text ("SELECT NOW()" )).fetchone ()
116+         conn .commit ()
117+         curr_time  =  time [0 ]
118+         assert  type (curr_time ) is  datetime 
119+     connector .close ()
0 commit comments