像所有 CRUD 一样,我需要将一些数据写入表中。当我将新数据写入表时,一切都像魅力一样。当我需要写入表中已经存在的数据(实际上是用相同的主键更新一些数据)时,问题就开始了。数据似乎没有写入表!我开始尝试使用 session.merge() 更新数据,但后来尝试了一种更暴力的方法,即在表中查询相同的 primary_key、删除它以及添加和刷新更改的对象。在某些地方,如果基本的添加和刷新失败,其余的都不起作用。我会很高兴在这里提供线索。
编码:
def flush(obj_Instance, id):
"""
taking care of the sqlalchemy flushing
params:
Instance: an object Instance to flush into
id: the unique object instance id
"""
DBSession2.add(obj_Instance)
try:
try:
DBSession2.flush()
print ("flushed:", str(obj_Instance))
except (FlushError, IntegrityError) as err:
DBSession2.rollback()
if ('conflicts with persistent instance' in str(err)) or ('Duplicate key was ignored' in str(err)):
transaction.begin()
#my original slick take:
DBSession2.merge(obj_instance) # but after it failed to update correctly I changed to a more brute force approach
#DBSession2.flush() #to save the merge
#from here on trying to brute force it
#saving for further reference - another try
newInstance = deepcopy(obj_Instance)
print ("deleting: %s" % id)
DBSession2.query(type(obj_Instance)).filter_by(ids = id).delete()
DBSession2.flush() #at this point, I was so desperate for this to work I literated the code with flush commands.
DBSession2.add(newInstance)
DBSession2.flush()
return
else:
raise #handling the case of the same key problem isn't the source of conflicts
except Exception as err: # supposed to find out the error type and message
# the code doesn't get here, only in real exceptions it was planned to catch, 3 rows in 10,000 uploaded to the db
#TODO: make this less general and more specific
print str(err)
write_log(num=id, msg="some sql or sqlalchemy error use num %s as id identifier with object: %s" % (id, obj_Instance.name), timestamp=
datetime.now(), errtype="sql error", log=str(err))
DBSession2.rollback()
transaction.begin()
使用带有 pyodbc 2.1.11 和 tg 2.1 的 sqlalchemy 0.7.3 vs mssql 2005(事务管理器带有 tg,我认为是基于事务的)