変更されたドキュメントをCassandra DBに新しいキーで挿入しようとしています。エラーメッセージが指している問題の原因を特定するのに苦労しています。他のユーザーを探すとき同様の問題があった回答はキーに関連しているようで、私の場合、Noneはいくつかのキーの値にすぎません。この問題を解決するにはどうすればよいですか?
keys = ','.join(current.keys())
params = [':' + x for x in current.keys()]
values = ','.join(params)
query = "INSERT INTO wiki.pages (%s) Values (%s)" % (keys, values)
query = query.encode('utf-8')
cursor.execute(query, current)
クエリと現在のデータは次のとおりです。
INSERT INTO wiki.pages (changed,content,meta,attachment,revision,page,editor)
VALUES (:changed,:content,:meta,:attachment,:revision,:page,:editor)
{
u'changed': '2013-02-15 16:31:49',
u'content': 'Testing',
u'meta': None,
u'attachment': None,
u'revision': 2,
u'page': u'FrontPage',
u'editor': 'Anonymous'
}
これは次のエラーで失敗します。
cql.apivalues.ProgrammingError:
Bad Request: line 1:123 no viable alternative at input 'None'
「実行可能な代替がない」とは、一部のキーのデータ型がその列ファミリーの列のスキーマと一致しないことを意味しますが、残念ながらエラーメッセージにはその旨が明記されていません。
私の場合、メタのデータ型は次のとおりです。
map<text,text>
このため、Noneは挿入時に悪い値と見なされていました。挿入する前にNoneを空のdictに置き換えることで問題を修正しました:
if current['meta'] is None:
current['meta'] = dict()
CQLドライバーはマップタイプの新しい値として空のdictを受け入れますが、マップ列をクエリすると空の場合はNoneが返されますが、Noneは許可されません。
Noneを返し、Noneを受け入れないことは直感的に感じられなかったため、後で、列のリストではなく列のマップを返し、MapType、ListType、またはSetTypeがNoneを返したかどうかを確認する、cursor.fetchone()のカスタムラッパーを作成することにしました。 。 None値がある場合は、空のdict()、list()、またはset()に置き換えて、変更されたデータをCassandraに挿入するときに発生したような問題を回避します。これはうまく動作するようです。