Python Mongodb
Python Mongodb
title: python-mongodb
date: 2018-10-23 09:27:55
tags: Python
categories: Language
---
use PyMongo
# Getting a Database
```python
# attribute style access
db = client.test_database
# Getting a Collection
```python
collection = db.test_collection
collection = db['test-collection']
```
<!-- more -->
# 插入数据
```python
collection.insert({'code': code, 'startDate': start_date, 'endDate': end_date,
'klines': klines})
```
## 防止插入重复数据
```python
# 单个字段唯一索引,通过建立索引保证不会重复,降序排列
t_codes.create_index([('trade_date', pymongo.DESCENDING)], unique=True,
background=True)
```
# Error
```
解决 bson.errors.InvalidDocument: Cannot encode object:错误的一种方法
这是因为 pandas 库在读取数值型值时返回的结果不是整型或者浮点型,而是 numpy.int64 类型的一个对象,
mongodb 是无法对一个对象进行编码存储的,所以这里需要对读取到的结果进行强制类型转换
dates = []
for i in range(0, 2):
print(cal.iloc[i]['cal_date'], cal.iloc[i]['is_open'])
print(cal.iloc[i]['cal_date'] + ' %d' %cal.iloc[i]['is_open'])
a = int(cal.iloc[i]['is_open'])
print(type(a))
dates.append({'cal_date':cal.iloc[i]['cal_date'], 'is_open':int(cal.iloc[i]
['is_open'])})
result = calender.insert_many(dates)
print(result)
print(result.inserted_ids)
```
# 查询记录
## 查询返回 datafram
没有数据时返回 datafram 空值
```python
t_data = db[code['ts_code']]
cursor_result = t_data.find(
{'ts_code': code['ts_code'], 'trade_date': {'$gte': start_date.strftime('%Y%m
%d'),
'$lte': end_date.strftime('%Y%m
%d')}}).sort('trade_date',
pymongo.DESCENDING)
labels = ['ts_code', 'trade_date', 'open', 'high', 'low', 'close', 'vol', 'amount']
df = pd.DataFrame(list(cursor_result), columns=labels)
```
## 列出数据库,集合
```python
# 列出数据库
conn.list_database_names()
# 旧版本
conn.database_names()
# 列出集合
db.list_collection_names
# 旧版本
db.collection_names()
```
## 查询所有数据
```python
# 查询集合中的所有文档记录(表中的行记录)
myColl.find()
# 返回一个查询结果的游标,可迭代对象
pymongo.DESCENDING)
for value in result:
if value['is_open']:
return datetime.datetime.strptime(value['cal_date'], '%Y%m%d')
print('Warning: xx')
# 获得一个游标操作对象,并迭代
rows = handler.find()
for row in rows:
print(row)
```
```python
b. 查询限定操作(也就是 sql 中的 where 语句)
i. myColl.find({'name':'liming'}) 查询集合中 字段 name = liming 的记录
1) 注意:括号内部是一个 字典,或者 json 格式的数据(其实都一个卵样)
2) 字典 key = 集合内文档的字段,value = 字段的值
3) 相当于 sql 中:
select *
from myColl
where name = 'liming'
ii. 一些高级操作:
1) 比较操作:
a) 小于比较:
i) myColl.find({'age':{'$lt':30}}
ii) 查询 age 字段值 小于 30 的所有文档记录
iii) 注意:括号内是一个 字典
iv) 字典 key = 文档字段,value 是一个字典,其中 key = 比较操作符, value =比
较值
v) 相当于 sql 中:
select *
from myColl
where age < 30
b) 其他比较操作符
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
2) 组合查询:
a) 逻辑与 and
i) myColl.find({'name':'liming','age':30})
ii) 查询 name = liming 和 age = 30 的所有文档记录
iii) 注意:括号内是一个字典,两个元素。用 逗号分隔开,key = 字段,value=字段值
iv) 相当于 sql:
select *
from myColl
where name = 'liming' and age = 30
b) 逻辑或 or
i) myColl.find({'$or':[{'name':'liming'},{'age':30}]})
ii) 查询 name = 'liming' 或 age = 30 的所有文档记录
iii) 注意:括号内是一个字典,key = '$or' 逻辑或操作符,value = 一个列表
列表内是两个字典,key = 字段,value=字段值
iv) 相当于 sql:
select *
from myColl
where name = 'liming' or age = 30
3) 对查询结果进行排序:
a) myColl.find().sort('name',pymongo.DESCENDING)
i) 对查询结果按照字段 name 进行排序,默认为升序,可以指定排序方向,
DESCENDING 是降序
ii) 相当于 sql:
select *
from myColl
order by name DESC
b) myColl.find().sort([{'name':pymongo.DESEDING',
{'age':pymongo.DESEDING'}])
i) 对查询结果排序,指定排序方向为 降序,默认为升序。
先按照 name 字段排序,在按照 age 字段排序
ii) 相当于 sql:
select *
from myColl
order by name DESC ,age DESC
DESC 关键字只适用于 DESC 前面的字段,需要的话,可以对每个字段指定一次 DESC
```
## 查询返回 dataframe
```python
df = pd.DataFrame(list(t_daily.find({'trade_date': day}, {"_id": 0})))
```
## 删除
```python
# 删除数据库
conn.drop_database('stockAlgPluginData')
conn.drop_database('stockAlgPluginDoc')
# 删除集合
t_codes = db['codes']
t_codes.drop()
# 这里可以重新插入数据,会创建新的集合
# 也可以使用 db 操作
db.drop_collection(collection_name)
```
# 集合是否存在
```python
collection_list = dbDoc.collection_names()
if table_name not in collection_list:
pass
```
# 插入数据
```python
collection.insert({'code': code, 'startDate': start_date, 'endDate': end_date,
'klines': klines})
```
# Error
```
解决 bson.errors.InvalidDocument: Cannot encode object:错误的一种方法
这是因为 pandas 库在读取数值型值时返回的结果不是整型或者浮点型,而是 numpy.int64 类型的一个对象,
mongodb 是无法对一个对象进行编码存储的,所以这里需要对读取到的结果进行强制类型转换
dates = []
for i in range(0, 2):
print(cal.iloc[i]['cal_date'], cal.iloc[i]['is_open'])
print(cal.iloc[i]['cal_date'] + ' %d' %cal.iloc[i]['is_open'])
a = int(cal.iloc[i]['is_open'])
print(type(a))
dates.append({'cal_date':cal.iloc[i]['cal_date'], 'is_open':int(cal.iloc[i]
['is_open'])})
result = calender.insert_many(dates)
print(result)
print(result.inserted_ids)
```
# 连接数据库
```python
import pymongo
conn = pymongo.MongoClient('127.0.0.1', 27017)
# database name is stock
db = conn['stock']
#有密码连接
import pymongo
mongo_client = pymongo.MongoClient('127.0.0.1', 26666)
mongo_auth = mongo_client.admin #或 mongo_client['admin'] admin 为
authenticationDatabase
mongo_auth.authenticate('用户名', '密码')
```
## upsert
```python
collectionConfig.update({'_id': resultConfig['id']}, {'$set': {'trade_data': 1}},
True)
```
# 单条插入
```python
result = collection.insert_one(student)
print(result)
print(result.inserted_id)
```
# 批量插入
```python
# 创建集合,相当于表
t_codes = db['codes']
# 插入获取的代码
result = t_codes.insert_many(dataArr)
print(result)
print(result.inserted_ids)
```
# 索引
```python
t_codes = db['codes']
# 获取所有索引
all_index = t_codes.index_information()
# print(list(all_index))
# 判断有无索引
has_id_index = all_index.get("idx_ts_code", False)
if has_id_index:
# 是否为唯一索引
if all_index['idx_ts_code'].get('unique', False):
pass
else:
t_codes.drop_index("idx_ts_code")
t_codes.create_index([("ts_code", 1)], name='idx_ts_code', unique=True,
background=True)
else:
t_codes.create_index([("ts_code", 1)], name='idx_ts_code', unique=True,
background=True)
```
# 查找
## 返回是否为空
```python
if not results.count():
print('not empty')
else:
print('empty')
```
## 查询返回 datafram
没有数据时返回 datafram 空值
```python
t_data = db[code['ts_code']]
cursor_result = t_data.find(
{'ts_code': code['ts_code'], 'trade_date': {'$gte': start_date.strftime('%Y%m
%d'),
'$lte': end_date.strftime('%Y%m
%d')}}).sort('trade_date',
pymongo.DESCENDING)
labels = ['ts_code', 'trade_date', 'open', 'high', 'low', 'close', 'vol',
'amount']
df = pd.DataFrame(list(cursor_result), columns=labels)
```
## 查询一条
```python
# 查询第一条数据
row = handler.find_one()
print(row)
# 最后一条
row = handler.find_one(sort=[('_id', -1)])
```
## 选择到 dataframe
```python
t_codes = dbDoc['codes']
cursor = t_codes.find({'list_date':{'$lte': lt_date}}, {"_id": 0, "ts_code": 1,
"name": 1, "list_date": 1})
fields = ['ts_code','name','list_date']
df = DataFrame(list(cursor), columns=fields)
return df
```
## 排序
```python
rows = handler.find().sort('_id', -1)
for row in rows:
print(row) # 此时会倒序输出内容
```
## 时间范围
```python
result = t_codes.find({'trade_date':{'$gte':start,'$lte':end}}).sort('trade_date',
pymongo.DESCENDING)
```
```python
# 查询集合中的所有文档记录(表中的行记录)
myColl.find()
# 返回一个查询结果的游标,可迭代对象
result = t_calender.find(
{'cal_date': {'$gte': pre_base_date.strftime('%Y%m%d'),
'$lte': base_date.strftime('%Y%m%d')}}).sort('cal_date',
pymongo.DESCENDING)
for value in result:
if value['is_open']:
return datetime.datetime.strptime(value['cal_date'], '%Y%m%d')
print('Warning: xx')
```
```python
b. 查询限定操作(也就是 sql 中的 where 语句)
i. myColl.find({'name':'liming'}) 查询集合中 字段 name = liming 的记录
1) 注意:括号内部是一个 字典,或者 json 格式的数据(其实都一个卵样)
2) 字典 key = 集合内文档的字段,value = 字段的值
3) 相当于 sql 中:
select *
from myColl
where name = 'liming'
ii. 一些高级操作:
1) 比较操作:
a) 小于比较:
i) myColl.find({'age':{'$lt':30}}
ii) 查询 age 字段值 小于 30 的所有文档记录
iii) 注意:括号内是一个 字典
iv) 字典 key = 文档字段,value 是一个字典,其中 key = 比较操作符, value =比
较值
v) 相当于 sql 中:
select *
from myColl
where age < 30
b) 其他比较操作符
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
2) 组合查询:
a) 逻辑与 and
i) myColl.find({'name':'liming','age':30})
ii) 查询 name = liming 和 age = 30 的所有文档记录
iii) 注意:括号内是一个字典,两个元素。用 逗号分隔开,key = 字段,value=字段值
iv) 相当于 sql:
select *
from myColl
where name = 'liming' and age = 30
b) 逻辑或 or
i) myColl.find({'$or':[{'name':'liming'},{'age':30}]})
ii) 查询 name = 'liming' 或 age = 30 的所有文档记录
iii) 注意:括号内是一个字典,key = '$or' 逻辑或操作符,value = 一个列表
列表内是两个字典,key = 字段,value=字段值
iv) 相当于 sql:
select *
from myColl
where name = 'liming' or age = 30
3) 对查询结果进行排序:
a) myColl.find().sort('name',pymongo.DESCENDING)
i) 对查询结果按照字段 name 进行排序,默认为升序,可以指定排序方向,
DESCENDING 是降序
ii) 相当于 sql:
select *
from myColl
order by name DESC
b) myColl.find().sort([{'name':pymongo.DESEDING',
{'age':pymongo.DESEDING'}])
i) 对查询结果排序,指定排序方向为 降序,默认为升序。
先按照 name 字段排序,在按照 age 字段排序
ii) 相当于 sql:
select *
from myColl
order by name DESC ,age DESC
DESC 关键字只适用于 DESC 前面的字段,需要的话,可以对每个字段指定一次 DESC
```