Issues with Neon connector

So I am trying to use Neon as my db, for reading and updating a simple table. It was working wonders on local, but I am struggling to make it work on cloud. I’ve tried downgrading psycopg2 to 2.9.6, which made also to downgrade to python 3.11 but the error is the same. According to copilot and the sqlalchemy info, it is because the connection needs channel binding. Neon uses SCRAM-SHA-256 and it may work with MD5.

Note that since I need to update, I am making changes via using the Session directly with SQLAlchemy.

Relevant info:
https://steam-review.streamlit.app/

The error:

────────────────────── Traceback (most recent call last) ───────────────────────

  /home/adminuser/venv/lib/python3.11/site-packages/streamlit/runtime/scriptru  

  nner/exec_code.py:128 in exec_func_with_error_handling                        

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/streamlit/runtime/scriptru  

  nner/script_runner.py:669 in code_to_exec                                     

                                                                                

  /mount/src/steam-reviews-ai/main.py:300 in <module>                           

                                                                                

    297 β”‚   with col_analysis:                                                  

    298 β”‚   β”‚   if st.button("Generate Review Analysis"):                       

    299 β”‚   β”‚   β”‚   appid = df[df["name"]==appname].index[0]                    

  ❱ 300 β”‚   β”‚   β”‚   content_raw = manage_summary_by_appid(str(appid), total_re  

    301 β”‚   β”‚   β”‚   content = json.loads(content_raw)                           

    302 β”‚   β”‚   β”‚   content = trim_factors(content, summary['total_positive']/  

    303 β”‚   β”‚   β”‚   with col_banner:                                            

                                                                                

  /mount/src/steam-reviews-ai/main.py:37 in manage_summary_by_appid             

                                                                                

     34 def manage_summary_by_appid(target_appid: str, total_reviews: int):     

     35 β”‚   conn = st.connection("neon", type="sql")                            

     36 β”‚   session = conn.session                                              

  ❱  37 β”‚   result = session.get(Summary, target_appid)                         

     38 β”‚   json_summary = None                                                 

     39 β”‚   if result is not None:                                              

     40 β”‚   β”‚   if check_fresh_summary(result, total_reviews):                  

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/orm/session.py:  

  3694 in get                                                                   

                                                                                

    3691 β”‚   β”‚   :return: The object instance, or ``None``.                     

    3692 β”‚   β”‚                                                                  

    3693 β”‚   β”‚   """  # noqa: E501                                              

  ❱ 3694 β”‚   β”‚   return self._get_impl(                                         

    3695 β”‚   β”‚   β”‚   entity,                                                    

    3696 β”‚   β”‚   β”‚   ident,                                                     

    3697 β”‚   β”‚   β”‚   loading.load_on_pk_identity,                               

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/orm/session.py:  

  3873 in _get_impl                                                             

                                                                                

    3870 β”‚   β”‚                                                                  

    3871 β”‚   β”‚   if options:                                                    

    3872 β”‚   β”‚   β”‚   statement = statement.options(*options)                    

  ❱ 3873 β”‚   β”‚   return db_load_fn(                                             

    3874 β”‚   β”‚   β”‚   self,                                                      

    3875 β”‚   β”‚   β”‚   statement,                                                 

    3876 β”‚   β”‚   β”‚   primary_key_identity,                                      

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/orm/loading.py:  

  694 in load_on_pk_identity                                                    

                                                                                

     691 β”‚   β”‚   execution_options, {"_sa_orm_load_options": load_options}      

     692 β”‚   )                                                                  

     693 β”‚   result = (                                                         

  ❱  694 β”‚   β”‚   session.execute(                                               

     695 β”‚   β”‚   β”‚   q,                                                         

     696 β”‚   β”‚   β”‚   params=params,                                             

     697 β”‚   β”‚   β”‚   execution_options=execution_options,                       

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/orm/session.py:  

  2365 in execute                                                               

                                                                                

    2362 β”‚   β”‚                                                                  

    2363 β”‚   β”‚                                                                  

    2364 β”‚   β”‚   """                                                            

  ❱ 2365 β”‚   β”‚   return self._execute_internal(                                 

    2366 β”‚   β”‚   β”‚   statement,                                                 

    2367 β”‚   β”‚   β”‚   params,                                                    

    2368 β”‚   β”‚   β”‚   execution_options=execution_options,                       

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/orm/session.py:  

  2241 in _execute_internal                                                     

                                                                                

    2238 β”‚   β”‚                                                                  

    2239 β”‚   β”‚   bind = self.get_bind(**bind_arguments)                         

    2240 β”‚   β”‚                                                                  

  ❱ 2241 β”‚   β”‚   conn = self._connection_for_bind(bind)                         

    2242 β”‚   β”‚                                                                  

    2243 β”‚   β”‚   if _scalar_result and not compile_state_cls:                   

    2244 β”‚   β”‚   β”‚   if TYPE_CHECKING:                                          

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/orm/session.py:  

  2110 in _connection_for_bind                                                  

                                                                                

    2107 β”‚   β”‚   trans = self._transaction                                      

    2108 β”‚   β”‚   if trans is None:                                              

    2109 β”‚   β”‚   β”‚   trans = self._autobegin_t()                                

  ❱ 2110 β”‚   β”‚   return trans._connection_for_bind(engine, execution_options)   

    2111 β”‚                                                                      

    2112 β”‚   @overload                                                          

    2113 β”‚   def _execute_internal(                                             

  in _connection_for_bind:2                                                     

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/orm/state_chang  

  es.py:139 in _go                                                              

                                                                                

    136 β”‚   β”‚   β”‚   self._current_fn = fn                                       

    137 β”‚   β”‚   β”‚   self._next_state = _StateChangeStates.CHANGE_IN_PROGRESS    

    138 β”‚   β”‚   β”‚   try:                                                        

  ❱ 139 β”‚   β”‚   β”‚   β”‚   ret_value = fn(self, *arg, **kw)                        

    140 β”‚   β”‚   β”‚   except:                                                     

    141 β”‚   β”‚   β”‚   β”‚   raise                                                   

    142 β”‚   β”‚   β”‚   else:                                                       

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/orm/session.py:  

  1189 in _connection_for_bind                                                  

                                                                                

    1186 β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   "for the given Connection's Engine"        

    1187 β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   )                                              

    1188 β”‚   β”‚   β”‚   β”‚   else:                                                  

  ❱ 1189 β”‚   β”‚   β”‚   β”‚   β”‚   conn = bind.connect()                              

    1190 β”‚   β”‚   β”‚   β”‚   β”‚   local_connect = True                               

    1191 β”‚   β”‚   β”‚                                                              

    1192 β”‚   β”‚   β”‚   try:                                                       

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py:  

  3273 in connect                                                               

                                                                                

    3270 β”‚   β”‚                                                                  

    3271 β”‚   β”‚   """                                                            

    3272 β”‚   β”‚                                                                  

  ❱ 3273 β”‚   β”‚   return self._connection_cls(self)                              

    3274 β”‚                                                                      

    3275 β”‚   def raw_connection(self) -> PoolProxiedConnection:                 

    3276 β”‚   β”‚   """Return a "raw" DBAPI connection from the connection pool.   

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py:  

  147 in __init__                                                               

                                                                                

     144 β”‚   β”‚   β”‚   try:                                                       

     145 β”‚   β”‚   β”‚   β”‚   self._dbapi_connection = engine.raw_connection()       

     146 β”‚   β”‚   β”‚   except dialect.loaded_dbapi.Error as err:                  

  ❱  147 β”‚   β”‚   β”‚   β”‚   Connection._handle_dbapi_exception_noconnection(       

     148 β”‚   β”‚   β”‚   β”‚   β”‚   err, dialect, engine                               

     149 β”‚   β”‚   β”‚   β”‚   )                                                      

     150 β”‚   β”‚   β”‚   β”‚   raise                                                  

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py:  

  2436 in _handle_dbapi_exception_noconnection                                  

                                                                                

    2433 β”‚   β”‚   β”‚   raise newraise.with_traceback(exc_info[2]) from e          

    2434 β”‚   β”‚   elif should_wrap:                                              

    2435 β”‚   β”‚   β”‚   assert sqlalchemy_exception is not None                    

  ❱ 2436 β”‚   β”‚   β”‚   raise sqlalchemy_exception.with_traceback(exc_info[2]) fr  

    2437 β”‚   β”‚   else:                                                          

    2438 β”‚   β”‚   β”‚   assert exc_info[1] is not None                             

    2439 β”‚   β”‚   β”‚   raise exc_info[1].with_traceback(exc_info[2])              

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py:  

  145 in __init__                                                               

                                                                                

     142 β”‚   β”‚                                                                  

     143 β”‚   β”‚   if connection is None:                                         

     144 β”‚   β”‚   β”‚   try:                                                       

  ❱  145 β”‚   β”‚   β”‚   β”‚   self._dbapi_connection = engine.raw_connection()       

     146 β”‚   β”‚   β”‚   except dialect.loaded_dbapi.Error as err:                  

     147 β”‚   β”‚   β”‚   β”‚   Connection._handle_dbapi_exception_noconnection(       

     148 β”‚   β”‚   β”‚   β”‚   β”‚   err, dialect, engine                               

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/engine/base.py:  

  3297 in raw_connection                                                        

                                                                                

    3294 β”‚   β”‚   β”‚   :ref:`dbapi_connections`                                   

    3295 β”‚   β”‚                                                                  

    3296 β”‚   β”‚   """                                                            

  ❱ 3297 β”‚   β”‚   return self.pool.connect()                                     

    3298                                                                        

    3299                                                                        

    3300 class OptionEngineMixin(log.Identified):                               

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/pool/base.py:44  

  9 in connect                                                                  

                                                                                

     446 β”‚   β”‚   the pool.                                                      

     447 β”‚   β”‚                                                                  

     448 β”‚   β”‚   """                                                            

  ❱  449 β”‚   β”‚   return _ConnectionFairy._checkout(self)                        

     450 β”‚                                                                      

     451 β”‚   def _return_conn(self, record: ConnectionPoolEntry) -> None:       

     452 β”‚   β”‚   """Given a _ConnectionRecord, return it to the :class:`_pool.  

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/pool/base.py:12  

  64 in _checkout                                                               

                                                                                

    1261 β”‚   β”‚   fairy: Optional[_ConnectionFairy] = None,                      

    1262 β”‚   ) -> _ConnectionFairy:                                             

    1263 β”‚   β”‚   if not fairy:                                                  

  ❱ 1264 β”‚   β”‚   β”‚   fairy = _ConnectionRecord.checkout(pool)                   

    1265 β”‚   β”‚   β”‚                                                              

    1266 β”‚   β”‚   β”‚   if threadconns is not None:                                

    1267 β”‚   β”‚   β”‚   β”‚   threadconns.current = weakref.ref(fairy)               

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/pool/base.py:71  

  3 in checkout                                                                 

                                                                                

     710 β”‚   β”‚   if TYPE_CHECKING:                                              

     711 β”‚   β”‚   β”‚   rec = cast(_ConnectionRecord, pool._do_get())              

     712 β”‚   β”‚   else:                                                          

  ❱  713 β”‚   β”‚   β”‚   rec = pool._do_get()                                       

     714 β”‚   β”‚                                                                  

     715 β”‚   β”‚   try:                                                           

     716 β”‚   β”‚   β”‚   dbapi_connection = rec.get_connection()                    

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/pool/impl.py:17  

  9 in _do_get                                                                  

                                                                                

    176 β”‚   β”‚   β”‚   try:                                                        

    177 β”‚   β”‚   β”‚   β”‚   return self._create_connection()                        

    178 β”‚   β”‚   β”‚   except:                                                     

  ❱ 179 β”‚   β”‚   β”‚   β”‚   with util.safe_reraise():                               

    180 β”‚   β”‚   β”‚   β”‚   β”‚   self._dec_overflow()                                

    181 β”‚   β”‚   β”‚   β”‚   raise                                                   

    182 β”‚   β”‚   else:                                                           

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/util/langhelper  

  s.py:224 in __exit__                                                          

                                                                                

     221 β”‚   β”‚   β”‚   exc_type, exc_value, exc_tb = self._exc_info               

     222 β”‚   β”‚   β”‚   assert exc_value is not None                               

     223 β”‚   β”‚   β”‚   self._exc_info = None  # remove potential circular refere  

  ❱  224 β”‚   β”‚   β”‚   raise exc_value.with_traceback(exc_tb)                     

     225 β”‚   β”‚   else:                                                          

     226 β”‚   β”‚   β”‚   self._exc_info = None  # remove potential circular refere  

     227 β”‚   β”‚   β”‚   assert value is not None                                   

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/pool/impl.py:17  

  7 in _do_get                                                                  

                                                                                

    174 β”‚   β”‚                                                                   

    175 β”‚   β”‚   if self._inc_overflow():                                        

    176 β”‚   β”‚   β”‚   try:                                                        

  ❱ 177 β”‚   β”‚   β”‚   β”‚   return self._create_connection()                        

    178 β”‚   β”‚   β”‚   except:                                                     

    179 β”‚   β”‚   β”‚   β”‚   with util.safe_reraise():                               

    180 β”‚   β”‚   β”‚   β”‚   β”‚   self._dec_overflow()                                

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/pool/base.py:39  

  0 in _create_connection                                                       

                                                                                

     387 β”‚   def _create_connection(self) -> ConnectionPoolEntry:               

     388 β”‚   β”‚   """Called by subclasses to create a new ConnectionRecord."""   

     389 β”‚   β”‚                                                                  

  ❱  390 β”‚   β”‚   return _ConnectionRecord(self)                                 

     391 β”‚                                                                      

     392 β”‚   def _invalidate(                                                   

     393 β”‚   β”‚   self,                                                          

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/pool/base.py:67  

  5 in __init__                                                                 

                                                                                

     672 β”‚   β”‚                                                                  

     673 β”‚   β”‚   self.__pool = pool                                             

     674 β”‚   β”‚   if connect:                                                    

  ❱  675 β”‚   β”‚   β”‚   self.__connect()                                           

     676 β”‚   β”‚   self.finalize_callback = deque()                               

     677 β”‚                                                                      

     678 β”‚   dbapi_connection: Optional[DBAPIConnection]                        

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/pool/base.py:90  

  1 in __connect                                                                

                                                                                

     898 β”‚   β”‚   β”‚   pool.logger.debug("Created new connection %r", connection  

     899 β”‚   β”‚   β”‚   self.fresh = True                                          

     900 β”‚   β”‚   except BaseException as e:                                     

  ❱  901 β”‚   β”‚   β”‚   with util.safe_reraise():                                  

     902 β”‚   β”‚   β”‚   β”‚   pool.logger.debug("Error on connect(): %s", e)         

     903 β”‚   β”‚   else:                                                          

     904 β”‚   β”‚   β”‚   # in SQLAlchemy 1.4 the first_connect event is not used b  

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/util/langhelper  

  s.py:224 in __exit__                                                          

                                                                                

     221 β”‚   β”‚   β”‚   exc_type, exc_value, exc_tb = self._exc_info               

     222 β”‚   β”‚   β”‚   assert exc_value is not None                               

     223 β”‚   β”‚   β”‚   self._exc_info = None  # remove potential circular refere  

  ❱  224 β”‚   β”‚   β”‚   raise exc_value.with_traceback(exc_tb)                     

     225 β”‚   β”‚   else:                                                          

     226 β”‚   β”‚   β”‚   self._exc_info = None  # remove potential circular refere  

     227 β”‚   β”‚   β”‚   assert value is not None                                   

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/pool/base.py:89  

  7 in __connect                                                                

                                                                                

     894 β”‚   β”‚   self.dbapi_connection = None                                   

     895 β”‚   β”‚   try:                                                           

     896 β”‚   β”‚   β”‚   self.starttime = time.time()                               

  ❱  897 β”‚   β”‚   β”‚   self.dbapi_connection = connection = pool._invoke_creator  

     898 β”‚   β”‚   β”‚   pool.logger.debug("Created new connection %r", connection  

     899 β”‚   β”‚   β”‚   self.fresh = True                                          

     900 β”‚   β”‚   except BaseException as e:                                     

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/engine/create.p  

  y:646 in connect                                                              

                                                                                

    643 β”‚   β”‚   β”‚   β”‚   β”‚   if connection is not None:                          

    644 β”‚   β”‚   β”‚   β”‚   β”‚   β”‚   return connection                               

    645 β”‚   β”‚   β”‚                                                               

  ❱ 646 β”‚   β”‚   β”‚   return dialect.connect(*cargs, **cparams)                   

    647 β”‚   β”‚                                                                   

    648 β”‚   β”‚   creator = pop_kwarg("creator", connect)                         

    649                                                                         

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/sqlalchemy/engine/default.  

  py:625 in connect                                                             

                                                                                

     622 β”‚                                                                      

     623 β”‚   def connect(self, *cargs: Any, **cparams: Any) -> DBAPIConnection  

     624 β”‚   β”‚   # inherits the docstring from interfaces.Dialect.connect       

  ❱  625 β”‚   β”‚   return self.loaded_dbapi.connect(*cargs, **cparams)  # type:   

     626 β”‚                                                                      

     627 β”‚   def create_connect_args(self, url: URL) -> ConnectArgsType:        

     628 β”‚   β”‚   # inherits the docstring from interfaces.Dialect.create_conne  

                                                                                

  /home/adminuser/venv/lib/python3.11/site-packages/psycopg2/__init__.py:122    

  in connect                                                                    

                                                                                

    119 β”‚   β”‚   kwasync['async_'] = kwargs.pop('async_')                        

    120 β”‚                                                                       

    121 β”‚   dsn = _ext.make_dsn(dsn, **kwargs)                                  

  ❱ 122 β”‚   conn = _connect(dsn, connection_factory=connection_factory, **kwas  

    123 β”‚   if cursor_factory is not None:                                      

    124 β”‚   β”‚   conn.cursor_factory = cursor_factory                            

    125                                                                         

────────────────────────────────────────────────────────────────────────────────

OperationalError: (psycopg2.OperationalError) channel binding required but not 

supported by server's authentication request


(Background on this error at: https://sqlalche.me/e/20/e3q8)
1 Like

Nevermind. I solved it by using psycopg2-binary instead, I was a bit confused about the comment on the tutorial and thought it was preferred to use the other one.