title: Unable to retrieve database objects in Flask test case session
body: <p>I am testing an API created using <code>flask-restful</code>, <code>sqlalchemy</code>, <code>flask-sqlalchemy</code> and <code>factory-boy</code>. </p>
  
  <p>I have encountered a strange issue where objects created before <code>GET</code> requests using <code>factory</code> are available but objects created before post/put calls are unavailable.</p>
  
  <p>I have set up a test case class based on <code>flask-testing</code>:</p>
  
  <pre><code># tests/common.py
  from flask_testing import TestCase as FlaskTestCase
  
  from app import create_app
  from database import db
  from config import TestConfig
  
  
  class TestCase(FlaskTestCase):
      def create_app(self):
          return create_app(TestConfig)
  
      def setUp(self):
      db.create_all()
  
      def tearDown(self):
          db.session.remove()
          db.drop_all()
  </code></pre>
  
  <p>Test factory:</p>
  
  <pre><code># tests/factory.py
  
  import factory
  
  from database import db
  
  from ..models import Item
  
  class ItemFactory(factory.alchemy.SQLAlchemyModelFactory):
      class Meta:
          model = Item
          sqlalchemy_session = db.session
  </code></pre>
  
  <p>Resources:</p>
  
  <pre><code># resources.py
  from flask import request
  from flask_restful import Resource
  
  from database import db
  from .models import Item
  from .serializers import ItemSerializer
  
  class ItemResource(Resource):
      def get(self, symbol):
          obj = db.session(Item).filter(Item.symbol == symbol).first_or_404()
      return ItemSerializer(obj).data
  
      def put(self, symbol):
          params = request.get_json(silent=True)
          query = db.session(Item).filter(Item.symbol == symbol).update(params)
  
          db.session.commit()
  
          obj = db.session(Item).filter(Item.symbol == symbol).first_or_404()
          return ItemSerializer(obj).data
  </code></pre>
  
  <p>Tests:</p>
  
  <pre><code># tests/test_resources.py
  import json
  
  from tests.common import TestCase
  from tests.factory import ItemFactory
  
  
  def parse_response(response):
      return json.loads(response.get_data().decode())
  
  
  class ResourcesTest(TestCase):
      def test_get_item(self):
          symbol = 'TEST'
          ItemFactory(symbol=symbol)
  
          response = self.client.get('/api/v1/items/%s' % symbol)
          results = parse_response(response)
  
          self.assertEqual(response.status_code, 200)
          self.assertEqual(results['symbol'], symbol)
  
      def test_update_item(self):
          symbol = 'TEST'
          new_symbol = 'TEST_NEW'
          ItemFactory(symbol=symbol)
  
          response = self.client.put('/api/v1/items/%s' % symbol, json={'symbol': new_symbol})
          results = parse_response(response)
  
          self.assertEqual(response.status_code, 200)
  </code></pre>
  
  <p>In <code>test_update_item</code> I receive a 404 instead. Before we enter <code>self.client.put</code>, checking the database shows that the new <code>Item</code> was created. However, when we reach the <code>put</code> method in the resource, <code>db.session(Item).query.all()</code> returns an empty array.</p>
  
  <p>From <code>flask-testing</code> documentation, I spotted this paragraph:</p>
  
  <p><code>
  Another gotcha is that Flask-SQLAlchemy also removes the session instance at the end of every request (as should any thread safe application using SQLAlchemy with scoped_session). Therefore the session is cleared along with any objects added to it every time you call client.get() or another client method.
  </code></p>
  
  <p>I believe that the issue lies with the way sessions are treated but have not been able to come out with any solutions to ensure that my tests pass. Another interesting observation was that for <code>self.client.put</code> or <code>self.client.post</code>, if I change the data being posted as <code>self.client.put('/some/url', data={'symbol': symbol})</code>, the objects will be available in the session.</p>