2015-02-04 50 views
3

我用的燒瓶SQLAlchemy的和具有以下列模型:爲什麼SQLAlchemy將hstore字段初始化爲空?

class Item(Model): 
    misc = Column(MutableDict.as_mutable(postgresql.HSTORE), nullable=False, 
        server_default='', 
        default=MutableDict.as_mutable(postgresql.HSTORE)) 

當我嘗試域分配給模型對象,似乎misc列是無,而不是一個空的字典:

my_item = Item() 
my_item.misc["foo"] = "bar" 
# TypeError: 'NoneType' object does not support item assignment 

如何配置模型以便新對象使用空字典進行初始化?

回答

3

這裏有兩個問題。首先,default應該是Python字典,而不是列類型的重複。其次,在初始化新實例時不使用default,只有在提交沒有爲該列設置值的實例時才使用default。所以你需要在初始化期間專門添加一個默認值。

from sqlalchemy.dialects.postgresql import HSTORE 
from sqlalchemy.ext.mutable import MutableDict 

class Item(db.Model): 
    misc = db.Column(MutableDict.as_mutable(HSTORE), nullable=False, default={}, server_default='') 

    def __init__(self, **kwargs): 
     kwargs.setdefault('misc', {}) 
     super(Item, self).__init__(**kwargs) 
item = Item() 
item.misc['foo'] = 'bar' 

關於這一點,有一個在設置這兩個defaultserver_default如果你永遠只能將使用這個從Python中沒有點。不過,也沒有害處。


我假設你知道你在這種特殊情況下需要一個HSTORE,但我還會指出,PostgreSQL有更普遍的JSON和JSONB類型了。

+0

這是我工作的:'misc = db.Column(MutableDict.as_mutable(HSTORE),nullable = False,server_default = db.text(「''」))''。通過這種方式,我在postgres的'misc'列中獲得了一個'DEFAULT'':: hstore',這導致在python中缺省爲空的'dict'。 – robkorv

0

有可能是一個更簡單的方法來做到這一點,但一種方法是創建一個自定義列類型轉換數據庫中的值,並返回。

下面是一個VARCHAR字段從序列化的文檔/反序列化JSON的例子:

http://docs.sqlalchemy.org/en/latest/orm/extensions/mutable.html#establishing-mutability-on-scalar-column-values

from sqlalchemy.types import TypeDecorator, VARCHAR 
import json 

class JSONEncodedDict(TypeDecorator): 
    "Represents an immutable structure as a json-encoded string." 

    impl = VARCHAR 

    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 

在你的情況,你可以檢查是否value爲None並返回一個空dict()相反,當寫入分貝時,你會檢查value是否是一個空字典,而不是寫None

如果你走這條路,再看看可變性的東西,所以JSONEncodedDict的變化會被注意到並被刷新。它看起來像你已經知道它,但只是爲了讀其他人。

希望有所幫助。

+0

但這不是HSTORE。由於這是PostgreSQL,因此如果需要的話,可以使用JSON和JSONB類型。 – davidism