dictをロードしてsqlite DBに/から保存したいのですが、簡単な方法で問題を解決しています。内容に基づいてフィルタリングなどができる必要はありませんので、文字列への簡単な変換は問題ありません。sqlalchemyのPython dicts
次善のものは外部キーです。巨大な例へのリンクを投稿しないでください。
dictをロードしてsqlite DBに/から保存したいのですが、簡単な方法で問題を解決しています。内容に基づいてフィルタリングなどができる必要はありませんので、文字列への簡単な変換は問題ありません。sqlalchemyのPython dicts
次善のものは外部キーです。巨大な例へのリンクを投稿しないでください。
あなたはテキストにシリアライズとデシリアライズを処理するためにsqlalchemy.types.TypeDecorator
をサブクラス化してカスタムタイプを作成することができます。これはまた、その辞書の変異を追跡する方法を示しており、an example in the SQLAlchemy docsに概説されている
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()
:
実装は
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
使用例のように見えるかもしれません。
このアプローチは、単に別の答えに彼のコメントにAlexGrönholm points outとして、正常に動作しませんPickleType
のpickler
引数の値としてjson
を渡すのに対して、Pythonのすべてのバージョンのために働く必要があります。
あなたは、1-N 関係をマッピングし、むしろ、その後dict
list
としてそれをマップする必要がある場合は、Dictionary Based Collections
を読んしかし、あなたはフィールドを意味する場合は、あなたが持っている、それを何を行うことができますあなたのPythonオブジェクトにマップされた文字列型のDBフィールド。しかし、同じ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)
ああ!素晴らしい! :) –
SQLAlchemyでは、dictの内容を変更することはできません.dictが設定された後に変更を加えると、永続化されません。 – Simon
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()
メソッドを持っている何か他のものとPicklerさんを変更することにより、直列化機構を変更することができます。 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
素敵な!私はそれを最初に試してみよう。 –
私はself._properties [k] = vを試してみると、 "TypeError: 'Column'オブジェクトはアイテムの割り当てをサポートしていません。 –
あなたの答えは完全ではないので受け入れられません。また、「受け入れられた答え」への言及もあり、これはどんな試行をも逸らし、その特定の状態を任意の答えに変えるものです。正しい答えで始めてください。そして、もし必要ならば、他人が最後にやったことを含めてください。 –
@JonasByström私は現在受け入れられている回答への参照を削除し、少し例を拡張しました – karlson
これは最初に設定したときに機能しました。しかし、私のモデルに新しいフィールドを追加した後( 'product_count = db.Column(db.Integer)')、mysqlへの変更をマイグレートするときに次のエラーが表示されます: 'NameError:name 'TextPickleType' is not defined – iamlolz