Issue 1:
Migrated issue, originally created by Anonymous

We are doing some stuff with history and have a little problem.

After commit, history has been reseted to empty state: there no value in unchanged and after attribute is changed there is no value in deleted.

Probably, it is a bug. If it is correct behaviour, how is it expained?

Both on 0.8.2 and dev versions. Here is a test case.

class HistoryTest(_fixtures.FixtureTest):
run_inserts = None

def test_commit_history(self):
from sqlalchemy.orm.attributes import get_history, History

User, users = self.classes.User, self.tables.users

m2 = sa.MetaData()
users_unbound = users.tometadata(m2)
mapper(User, users_unbound)

sess = Session(binds={User: self.metadata.bind})
u = User(id=1, name='daniel')
sess.add(u)
print get_history(u, 'name')
assert get_history(u, 'name') ==\
History(['daniel']('daniel'), (), ())

sess.commit()
print get_history(u, 'name')
assert get_history(u, 'name') == \
History((), ['daniel']('daniel'), ())
# fails: History((), (), ())

u.name = 'peter'
print get_history(u, 'name')
assert get_history(u, 'name') == \
History(['peter']('peter'), (), ['daniel']('daniel'))
# fails: History(['peter']('peter'), (), ())

Attachments: 2787.patch

Issue 2:
Unittest an API, where test code fixture is trying to create a resource and then get the response to verify the previous step, and then again to try to create the same resource again, SqlAlchemy is randomizing the exception between Integrity and Flush Error.

Libs:

Flask==1.0.2

Flask-Cors==3.0.6

Flask-SQLAlchemy==2.3.2

SQLAlchemy==1.2.7

Werkzeug==0.14.1

I have been working on that project for the last 10 month, all the time I have seen only Integrity error, not flush error.

new_item.before_created(request_data)
db.session.add(new_item)
new_item.after_created(request_data)
db.session.commit()

headers = {'Location': new_item.get_url()} if new_item.get_url() else None
return (jsonify({}), 201, headers) if headers else (jsonify({}), 201)
except KeyError as e:
raise ValidationError(
ErrorCode.MISSING_MANDATORY_DATA,
error_msg=f"the {e.args[0]} field is required.",
)
except ValueError as e:
raise ValidationError(ErrorCode.INVALID_REQUEST_DATA, error_msg=e.args[0])
except BadRequest:
raise ValidationError(ErrorCode.INVALID_REQUEST_FORMAT)
except IntegrityError:
raise ValidationError(ErrorCode.INTEGRITY_ERROR, status_code=409)
except Conflict as e:
raise ValidationError(e.description, status_code=409)
finally:
db.session.rollback()

TEST CODE:

def test_create_new_product(self):
Product.delete(self.product_no, True)

# create a asset with the request data.
response = self.client.post(
"/assets/",
content_type="application/json",
data=json.dumps(self.default_req_data),
)
res_data = json.loads(response.data.decode())
self.assertEqual({}, res_data)
self.assertEqual(response.status_code, 201)

# check the asset that we already created.
response = self.client.get(
"/assets/{0}".format(self.product_no), content_type="application/json"
)
res_data = json.loads(response.data.decode())
self.assertEqual(response.status_code, 200)

for key in self.default_req_data.keys():
self.assertEqual(self.default_req_data[key], res_data[key])

# try create duplicated asset
response = self.client.post(
"/assets/",
content_type="application/json",
data=json.dumps(self.default_req_data),
)
res_data = json.loads(response.data.decode())
self.assertEqual(response.status_code, 409)

This fixture is called by several other fixtures but all them get Integrity error except one of them is getting flushError.

If I run all the test together I am facing this issue, alone it works fine.