gunicorn/nginx 스택과 함께 실행되는 Flask REST API가 있습니다. API가 실행되는 각 스레드마다 한 번 설정된 전역 SQLAlchemy 세션이 있습니다. 필자는 API의 단위 테스트를 실행하기 위해 endpoint/test /를 설정했습니다. 정리 절 : 하나 개의 테스트 데이터베이스에 무언가를 추가하는 POST 요청을 만들고, 다음 마지막을 가지고Flask SQLAlchemy 세션이 동기화되지 않았습니다.
def test_something():
try:
url = "http://myposturl"
data = {"content" : "test post"}
headers = {'content-type': 'application/json'}
result = requests.post(url, json=data, headers=headers).json()
validate(result, myschema)
finally:
db.sqlsession.query(MyTable).filter(MyTable.content == "test post").delete()
db.sqlsession.commit()
문제는 그 POST 요청이 이제 만든 "테스트 포스트"가되는 스레드 개체가 세션에 있지만 데이터베이스에 이러한 개체가 없습니다. 테스트가 실행 된 스레드가 데이터베이스에서 해당 개체를 삭제했기 때문입니다. 그래서 서버에 GET 요청을하면 약 4 번 (4 명의 gunicorn 작업자가 있음), "테스트 포스트"개체가 생기고 4 번은 3 번이 나옵니다. 이것은 스레드가 각각 자신의 세션 개체를 가지고 있기 때문에 동기를 잃고 있지만 실제로 그것에 대해 어떻게해야할지 모르겠다. ...
다음은 SQLAlchemy 세션에 대한 나의 설정이다 :
def connectSQLAlchemy():
import sqlalchemy
import sqlalchemy.orm
engine = sqlalchemy.create_engine(connection_string(DBConfig.USER, DBConfig.PASSWORD, DBConfig.HOST, DBConfig.DB))
session_factory = sqlalchemy.orm.sessionmaker(bind=engine)
Session = sqlalchemy.orm.scoped_session(session_factory)
return Session()
# Create a global session for everyone
sqlsession = connectSQLAlchemy()
나는 당신이 말한대로했는데 새로운 APIResource (Resource) 클래스의 __init__ 함수에 self.session = db.Session()을 넣었지만 같은 문제가있다. 데이터베이스에 뭔가를 넣고 별도의 스레드에서 삭제하지만 추가 스레드는 그 사실을 기억합니다. – Scott
@Scott 동일한 요청 * 내에 여러 스레드 *가 있다고 말하는 것입니까? – univerio
번호. 그냥 gunicorn 스레드. 이 솔루션의 문제점은 어딘가에 요청이 끝날 때 세션을 해체해야한다는 것입니다. – Scott