aeo*_*ros 7 python mongodb pymongo
我正在尝试使用PyMongo将文档(在本例中为twitter信息)插入Mongo数据库.
如下所示,tweets_listdt [0]与.完全相同
{
'created_at': u'Sun Aug 03 17:07:24 +0000 2014',
'id': 2704548373,
'name': u'NoSQL',
'text': u'RT @BigdataITJobs: Data Scientist \u2013 Machine learning, Python, Pandas, Statistics @adam_rab in London, United Kingdom http://t.co/pIIJVPCuN8\u2026'
}
Run Code Online (Sandbox Code Playgroud)
但我无法将tweets_listdt [0]保存到我的Mongodb中,而我可以使用后者保存.
In[529]: tweets_listdt[0] == {'created_at': u'Sun Aug 03 17:07:24 +0000 2014',
'id': 2704548373,
'name': u'NoSQL',
'text': u'RT @BigdataITJobs: Data Scientist \u2013 Machine learning, Python, Pandas, Statistics @adam_rab in London, United Kingdom http://t.co/pIIJVPCuN8\u2026'}
Out[528]: **True**
Run Code Online (Sandbox Code Playgroud)
这个失败了:
In[530]: tweetsdb.save(tweets_listdt[0])
tweetsdb.save({'created_at': u'Sun Aug 03 17:07:24 +0000 2014',
'id': 2704548373,
'name': u'NoSQL',
'text': u'RT @BigdataITJobs: Data Scientist \u2013 Machine learning, Python, Pandas, Statistics @adam_rab in London, United Kingdom http://t.co/pIIJVPCuN8\u2026'})
Traceback (most recent call last):
File "D:\Program Files\Anaconda\lib\site-packages\IPython\core\interactiveshell.py", line 3035, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-529-b1b81c04d5ad>", line 1, in <module>
tweetsdb.save(tweets_listdt[0])
File "D:\Program Files\Anaconda\lib\site-packages\pymongo\collection.py", line 1903, in save
check_keys, manipulate, write_concern)
File "D:\Program Files\Anaconda\lib\site-packages\pymongo\collection.py", line 430, in _insert
gen(), check_keys, self.codec_options, sock_info)
InvalidDocument: **Cannot encode object: 2704548373**
Run Code Online (Sandbox Code Playgroud)
这个工作正常:
In[531]: tweetsdb.save({'created_at': u'Sun Aug 03 17:07:24 +0000 2014',
'id': 2704548373,
'name': u'NoSQL',
'text': u'RT @BigdataITJobs: Data Scientist \u2013 Machine learning, Python, Pandas, Statistics @adam_rab in London, United Kingdom http://t.co/pIIJVPCuN8\u2026'})
Out[530]: **ObjectId('554b38d5c3d89c09688b1149')**
Run Code Online (Sandbox Code Playgroud)
谢谢伯尼.我正在使用的PyMongo版本是3.0.1.
这是对id的数据类型的检查:
In[36]:type(tweets_listdt[0]['id'])
Out[37]:long
Run Code Online (Sandbox Code Playgroud)
如果我只是使用:
for tweet in tweets_listdt:
tweetsdb.save(tweet)
Run Code Online (Sandbox Code Playgroud)
上面提到的错误会发生.
但如果我添加这一行,一切都没问题:
tweet['id'] = int(tweet['id'])
Run Code Online (Sandbox Code Playgroud)
而当我直接分配
tweets_listdtw = {'created_at': u'Sun Aug 03 17:07:24 +0000 2014',
'id': 2704548373,
'name': u'NoSQL',
'text': u'RT @BigdataITJobs: Data Scientist'}
Run Code Online (Sandbox Code Playgroud)
tweetsdb.save(tweets_listdtw)正在运行,并且
print type(tweets_listdtw['id'])
<type 'numpy.int64'>
Run Code Online (Sandbox Code Playgroud)
再次感到困惑...所以绝对长型是好的......但是为什么在我将'id'改为int后,保存工作呢?
Oz1*_*123 12
你的问题是numpy.int64MongoDB的陌生问题.我曾经也有过一样的问题.
解决方案是将违规值转换为MongoDB将理解的数据类型,这里是我在代码中转换这些违规值的示例:
try:
collection.insert(r)
except pymongo.errors.InvalidDocument:
# Python 2.7.10 on Windows and Pymongo are not forgiving
# If you have foreign data types you have to convert them
n = {}
for k, v in r.items():
if isinstance(k, unicode):
for i in ['utf-8', 'iso-8859-1']:
try:
k = k.encode(i)
except (UnicodeEncodeError, UnicodeDecodeError):
continue
if isinstance(v, np.int64):
self.info("k is %s , v is %s" % (k, v))
v = int(v)
self.info("V is %s" % v)
if isinstance(v, unicode):
for i in ['utf-8', 'iso-8859-1']:
try:
v = v.encode(i)
except (UnicodeEncodeError, UnicodeDecodeError):
continue
n[k] = v
collection.insert(n)
Run Code Online (Sandbox Code Playgroud)
我希望这可以帮助你.
我非常喜欢奥兹的回答。使用 python 3 对其进行扩展:
def correct_encoding(dictionary):
"""Correct the encoding of python dictionaries so they can be encoded to mongodb
inputs
-------
dictionary : dictionary instance to add as document
output
-------
new : new dictionary with (hopefully) corrected encodings"""
new = {}
for key1, val1 in dictionary.items():
# Nested dictionaries
if isinstance(val1, dict):
val1 = correct_encoding(val1)
if isinstance(val1, np.bool_):
val1 = bool(val1)
if isinstance(val1, np.int64):
val1 = int(val1)
if isinstance(val1, np.float64):
val1 = float(val1)
new[key1] = val1
return new
Run Code Online (Sandbox Code Playgroud)
它对那些嵌套文档有递归,我认为 python 3 将所有字符串存储为 unicode,所以我删除了编码部分。
小智 6
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, numpy.integer):
return int(obj)
elif isinstance(obj, numpy.floating):
return float(obj)
elif isinstance(obj, numpy.ndarray):
return obj.tolist()
else:
return super(CustomEncoder, self).default(obj)
data_dict_1 = json.dumps(data_dict,cls=CustomEncoder)
data_dict_final = json.loads(data_dict_1)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11647 次 |
| 最近记录: |