I'm having an issue committing changes to pickle types (lists) in sqlalchemy. It will act as if nothing happened after the committal.
Here's my my function where I try to commit:
def commit_move(game_id, player, move):
game = game_query(game_id)
if player == 'human':
game.human_spaces.append(move)
if player == 'ai':
game.ai_spaces.append(move)
game.available_spaces.remove(move)
print game.human_spaces
print game.ai_spaces
print game.available_spaces
print "----"
session.add(game)
session.commit()
here's how the table is setup:
class Game(Base):
__tablename__ = 'game'
id = Column(Integer, primary_key=True)
human_spaces = Column(PickleType)
ai_spaces = Column(PickleType)
available_spaces = Column(PickleType)
here's the code I'm using to test it:
game_id = create_game()
print game_id
print get_available_spaces(game_id)
print get_human_spaces(game_id)
print get_ai_spaces(game_id)
print "---------"
commit_move(game_id, 'human', 7)
print get_available_spaces(game_id)
print get_human_spaces(game_id)
print get_ai_spaces(game_id)
and here's what the good ol' terminal is telling me:
1
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[]
[]
---------
[7]
[]
[1, 2, 3, 4, 5, 6, 8, 9]
----
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[]
[]
I'm sure it's something simple I'm missing here, but any help would be greatly appreciated!
The problem is that the ORM is not alerted to changes inside a mutable type, like a list. SQLAlchemy therefore offers mutation tracking with the sqlalchemy.ext.mutable
extension.
From the examples in the documentation , in particular with reference to the sqlalchemy.ext.mutable.MutableList
class, it looks like the column declaration should go (eg):
human_spaces = Column(MutableList.as_mutable(PickleType))
I quote from the documentation on the as_mutable
method: "This establishes listeners that will detect ORM mappings against the given type, adding mutation event trackers to those mappings."
I've written a package to help make this easy. You can choose different encodings, including pickle
, and easily dump and store objects to a database. It can connect to any database that sqlalchemy
understands. There is a dictionary interface to a SQL table, and you can store any type that dill
can serialize:
>>> import klepto
>>> db = klepto.archives.sqltable_archive('playgame')
>>> db['human'] = [1,2,3,4]
>>> db['ai'] = [1,2]
>>> db
sqltable_archive('sqlite:///:memory:?table=playgame', {'ai': [1, 2], 'human': [1, 2, 3, 4]}, cached=True)
>>> db.dump()
>>>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.