我正在编写一个需要与许多数据存储区通信的Flask API,AWS RDS上的Postgres就是其中之一。我想避免使用Flask-SQLAlchemy(尝试减少包依赖),并且鉴于我的用例非常简单,我认为标准的SQLAlchemy库应该足够了。这是我的models.py
文件:
class DriverPostgres:
def __init__(self):
self.connector = PostgresCredentials()
self.connection_str = 'postgresql+psycopg2://{}:{}@{}/{}'.format(...)
self.engine = create_engine(self.connection_str)
self.Session = scoped_session(
sessionmaker(autocommit=False, autoflush=True, bind=self.engine))
Base.metadata.create_all(bind=self.engine)
def get_user_by_email(self, email):
session = self.Session()
result = session.query(User).filter_by(email=email).first()
self.Session.remove()
return result
def register_user(self, ...):
user = User(...)
session = self.Session()
session.add(user)
try:
session.commit()
except IntegrityError:
return False
finally:
self.Session.remove()
return True
在我的Flask应用server.py
文件中,我在应用顶部导入DriverPostgres
并实例化driver_postgres = DriverPostgres()
,在处理请求时,我调用driver_postgres.get_user_by_email()
。首次加载应用程序时,此逻辑非常有效。我可以根据需要发送尽可能多的请求,没有任何问题。但是,如果我等待几分钟并再次点击应用程序,我会收到以下错误:
Traceback (most recent call last):
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/userserver.py", line 118, in login
response = driver_postgres.check_password(email, password)
File "/Users/usermodels.py", line 125, in check_password
user_to_check = self.get_user_by_email(email)
File "/Users/usermodels.py", line 154, in get_user_by_email
result = session.query(User).filter_by(email=email).first()
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2835, in first
ret = list(self[0:1])
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2627, in __getitem__
return list(res)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2935, in __iter__
return self._execute_and_instances(context)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2958, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 948, in execute
return meth(self, multiparams, params)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/sql/elements.py", line 269, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1060, in _execute_clauseelement
compiled_sql, distilled_params
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1200, in _execute_context
context)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1413, in _handle_dbapi_exception
exc_info
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 186, in reraise
raise value.with_traceback(tb)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
context)
File "/Users/user/.virtualenvs/demo/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 508, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
[SQL: ...] (Background on this error at: http://sqlalche.me/e/e3q8)
这是相当严重的。我花了很多时间浏览SO和许多教程,这似乎是一个标准的有效模式,所以我不确定出了什么问题。我不应该删除会话吗?我应该使用@app.teardown_appcontext
装饰器(似乎如果我现在就像我现在所做的那样删除会话,我不应该这样做)?我是否应该使用连接池(默认情况下默认情况下QueuePool
已启用)?如果它有帮助,我使用所有软件包的最新版本,Python 3.6.5和Postman将请求发送到服务器,该服务器运行在localhost:5000
。任何建议都将非常感谢 - 提前感谢!