我想加載/保存字典到/從我的sqlite數據庫,但我有一些問題找出一個簡單的方法來做到這一點。我根本不需要根據內容進行過濾等,所以簡單地轉換爲/從字符串轉換就可以了。sqlalchemy中的Python字典
次最好的事情是外鍵。請不要張貼大量例子的鏈接,如果我着眼於任何這些例子,我的頭就會爆炸。
我想加載/保存字典到/從我的sqlite數據庫,但我有一些問題找出一個簡單的方法來做到這一點。我根本不需要根據內容進行過濾等,所以簡單地轉換爲/從字符串轉換就可以了。sqlalchemy中的Python字典
次最好的事情是外鍵。請不要張貼大量例子的鏈接,如果我着眼於任何這些例子,我的頭就會爆炸。
您可以通過繼承sqlalchemy.types.TypeDecorator
處理序列化和反序列化到文本創建一個自定義類型。
的實現可能看起來像
import json
import sqlalchemy
from sqlalchemy.types import TypeDecorator
SIZE = 256
class TextPickleType(TypeDecorator):
impl = sqlalchemy.Text(SIZE)
def process_bind_param(self, value, dialect):
if value is not None:
value = json.dumps(value)
return value
def process_result_value(self, value, dialect):
if value is not None:
value = json.loads(value)
return value
用法示例:
class SomeModel(Base):
__tablename__ = 'the_table'
id = Column(Integer, primary_key=True)
json_field = Column(TextPickleType())
s = SomeEntity(json_field={'baked': 'beans', 'spam': 'ham'})
session.add(s)
session.commit()
這在an example in the SQLAlchemy docs概括,這也說明了如何跟蹤字典的突變。
這種方法應該工作的Python的所有版本,而只是傳遞json
作爲價值的PickleType
的pickler
參數不會在他的另一個答案評論正常工作,爲AlexGrönholm points out。
如果你需要映射1-N 關係,並將其映射爲dict
而不是list
,然後讀Dictionary Based Collections
但是,如果你說的是場,你可以做那麼它有一個字符串類型的數據庫字段,它被映射到您的Python對象。但是在同一個python對象上,你提供了一個屬性,它將是類型爲dict()的映射字符串字段的類型代理。 代碼示例(未測試):
class MyObject(object):
# fields (mapped automatically by sqlalchemy using mapper(...)
MyFieldAsString = None
def _get_MyFieldAsDict(self):
if self.MyFieldAsString:
return eval(self.MyFieldAsString)
else:
return {} # be careful with None and empty dict
def _set_MyFieldAsDict(self, value):
if value:
self.MyFieldAsString = str(value)
else:
self.MyFieldAsString = None
MyFieldAsDict = property(_get_MyFieldAsDict, _set_MyFieldAsDict)
啊!燦爛! :) – 2009-09-04 10:24:41
請注意,SQLAlchemy不會看到您修改字典的內容,因此您設置字典後對其進行的任何更改都不會被保留。 – Simon 2012-07-13 07:17:04
的SQLAlchemy的PickleType正好爲這個意思。
class SomeEntity(Base):
__tablename__ = 'some_entity'
id = Column(Integer, primary_key=True)
attributes = Column(PickleType)
# Just set the attribute to save it
s = SomeEntity(attributes={'baked': 'beans', 'spam': 'ham'})
session.add(s)
session.commit()
# If mutable=True on PickleType (the default) SQLAlchemy automatically
# notices modifications.
s.attributes['parrot'] = 'dead'
session.commit()
你可以改變改變了別的東西有dumps()
和loads()
方法皮克勒序列化機制。底層的存儲機制,通過繼承PickleType並重寫IMPL attritbute:
class TextPickleType(PickleType):
impl = Text
import json
class SomeOtherEntity(Base):
__tablename__ = 'some_other_entity'
id = Column(Integer, primary_key=True)
attributes = Column(TextPickleType(pickler=json))
+1:非常漂亮 – van 2009-09-04 13:03:56
可愛!我會在星期一做第一件事。 – 2009-09-05 21:51:49
當我嘗試self._properties [k] = v時,我可能會做出嚴重錯誤的事情。我得到「TypeError:'列'對象不支持項目分配」。 – 2009-09-07 07:04:32
你的答案不完整,所以不能接受。它還提到了「接受的答案」,該答案在任何答案中偏離了任何企圖並改變了該特定狀態。請先從正確的答案開始,並且(如果您必須)包括其他人在最後做錯了什麼。 – 2017-04-25 09:07:01
@JonasByström夠公平的,我已經刪除了對當前接受的答案的引用,並將示例擴展了一下 – karlson 2017-04-25 12:02:51
當我第一次設置它時,這個工作。然而,在我的模型('product_count = db.Column(db.Integer)')中添加一個新字段後,當將更改遷移到mysql時,它給了我以下錯誤:'NameError:name'TextPickleType'未定義' – iamlolz 2017-05-03 05:02:26