项目需求... 直接上码
- ORM文件
忘记说了,mysqldb的配置settings文件,要放在ORM文件同级目录下。
# -*- coding:utf-8 -*-
import os, sys
print(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from sqlalchemy import create_engine, update, Table, Column, Integer, String, MetaData, ForeignKey
from sqlalchemy.orm import Session
from sqlalchemy.ext.automap import automap_base
import pymysql
pymysql.install_as_MySQLdb()
from ..mytools.settings import mysqldb
import json, time
class MysqlSaveData(object):
"""
mysql数据库,自动映射工具类;
配置文件在当前工具类文件统计目录下的settings中的mysqdb
mysql:
'master_host': 主数据库ip
'slave_host': 从数据库ip
'master_port': 主数据库端口
'slave_port': 从数据库端口
'master_db': 主,所需映射数据库名称
'slave_db': 从,所需映射数据库名称
'master_user_name': 主数据库用户名
'slave_user_name': 从数据库用户名
'master_password': 主数据库密码
'slave_password': 从数据库密码
"""
# 主数据库
master_engine_str = "mysql+pymysql://" + mysqldb['master_user_name'] + ":" + mysqldb['master_password'] + "@" + \
mysqldb['master_host'] + ":" + str(mysqldb['master_port']) + "/" + mysqldb[
'master_db'] + "?charset=utf8mb4"
master_engine = create_engine(master_engine_str, echo=False) # echo: 是否打印映射时的sql语句
master_session = Session(master_engine)
master_Base = automap_base()
master_Base.prepare(master_engine, reflect=True)
# 从数据库
slave_engine_str = "mysql+pymysql://" + mysqldb['slave_user_name'] + ":" + mysqldb['slave_password'] + "@" + \
mysqldb['slave_host'] + ":" + str(mysqldb['slave_port']) + "/" + mysqldb[
'slave_db'] + "?charset=utf8mb4"
slave_engine = create_engine(slave_engine_str, echo=False) # echo: 是否打印映射时的sql语句
slave_session = Session(slave_engine)
slave_Base = automap_base()
slave_Base.prepare(slave_engine, reflect=True)
def __init__(self, table_name): # table_name
"""
创建表对象
:param table_name: 表名称
"""
self.table_name = table_name
self.master_table = self.master_Base.classes.__getitem__(key=table_name)
# print(self.master_table)
self.slave_table = self.slave_Base.classes.__getitem__(key=table_name)
def create_master_connection(self):
"""
创建主数据库连接对象
:return:
"""
def create_slave_connection(self, table_name):
"""
新建从数据库连接对象
:return:
"""
# 从数据库
slave_engine = create_engine(self.slave_engine_str, echo=False) # echo: 是否打印映射时的sql语句
slave_session = Session(slave_engine)
slave_Base = automap_base()
slave_Base.prepare(slave_engine, reflect=True)
slave_table = slave_Base.classes.__getitem__(key=table_name)
return slave_table, slave_session
def _update(self, dict_v, item, **kwargs):
"""
更新数据库数据;
如需更新数据,继承该类为父类,复写此_update()方法
:param kwargs: 查询条件;k:v形式;k为表内字段名称
:param dict_v: 所需更新的数据,字典类型
:param item: 爬虫爬取的数据,字典类型
:return:
"""
pass
def update_commit(self):
"""
更新数据专用提交接口
:return:
"""
try:
self.master_session.commit()
except Exception as e:
print('更新失败')
print(e)
self.master_session.rollback()
else:
print('更新成功')
finally:
self.master_session.close()
def _add(self, dict_v):
"""
新数据添加
:return:
"""
data = self.master_table(
**dict_v
)
self.master_session.add(data)
try:
self.master_session.commit()
except Exception as e:
print('插入失败')
print(e)
self.master_session.rollback()
else:
print('插入成功')
finally:
self.master_session.close()
def _find(self, **kwargs):
"""
单条查询
:param kwargs: 查询条件;k:v形式;k为表内字段名称
:return:
"""
result = self.slave_session.query(self.slave_table).filter_by(**kwargs).first()
return result
def process_data_and_save(self, dict_v, item=None, **kwargs):
"""
映射mysql已有数据库表结构
:param dict_v: 表内字段名称的复制,字典类型
:param kwargs: 查询条件,k:v形式; k为表内字段名称
:return:
"""
if not self._find(**kwargs):
# 添加新数据
self._add(dict_v)
else:
# 更新数据库数据
self._update(dict_v, item,**kwargs)
# 创建提交数据后的新从机连接对象
slave_table, slave_session = self.create_slave_connection(self.table_name)
# 返回当前插入成功数据id
result = slave_session.query(slave_table).filter_by(**kwargs).first().id
return result
if __name__ == '__main__':
item = {} # 需要插入的数据
# 表与数据字段映射关系;不设置默认为None
# 注意:如果字段的值为字符串以外数据,需要使用json转换,记得设置“ensure_ascii=False”
dict_v = dict(
content=item["content_list"] if isinstance(item['content_list'], str) else json.dumps(item['content_list'], ensure_ascii=False),
newstime=item["publish_date"],
title=item["title"],
sitename="",
author=item["authro"],
introduction=item["intro"]
)
m = MysqlSaveData(table_name='a_community_news')
ids = m.process_data_and_save(dict_v=dict_v, title=item['title'])
print(ids)
时间仓促,也没有na那么多的废话,多跑两下,基本都清楚了