利用redis协助mysql数据库搬迁
最近公司新项目上线,需要数据库搬迁,但新版本和老版本数据库差距比较大,关系也比较复杂。如果用传统办法,需要撰写很多mysql脚本,工程量虽然不大,但对于没有dba的公司来说,稍微有点难度。本人就勉为其难,用redis作为mysql中转站,先把原来的mysql数据转移到redis里面,再从redis转换到新的mysql。整个过程脉络清晰,脚本简单。
首先,公司之前的项目是,flask+sqlalchemy的方式,直接复制原来的model文件,稍微修改一下,就有以下代码。
# coding:utf-8 from sqlalchemy import create_engine, ForeignKey, Column, Integer, String, Text, DateTime, Boolean, and_, or_,\ SmallInteger, func, Numeric, select, Float, Table, TIMESTAMP, DECIMAL, desc from sqlalchemy.orm import relationship, backref, sessionmaker, scoped_session from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method, Comparator from sqlalchemy import event import redis import json mysql_info = "mysql://username:password@ip_address:3306/databasename?charset=utf8" redis_store = redis.Redis(host='127.0.0.1', port=6380, password='password', db=5) engine = create_engine(mysql_info, pool_recycle=7200) Base = declarative_base() class User(Base): __tablename__ = 'user' id = Column('id', Integer, primary_key=True) phone_number = Column('phone_number', String(11), index=True) password = Column('password', String(30)) nickname = Column('nickname', String(30), index=True, nullable=True) headpic = Column('headpic', String(100), nullable=True) register_time = Column('register_time', DateTime, index=True) email = Column('email', String(50), default='', index=True) real_name = Column('real_name', String(50), default='', index=True) user_admin = Column('user_admin', Integer, index=True, default=0) rc_token = Column('rc_token', String(100)) device_token = Column('device_token', String(100), unique=True, nullable=True) unit_id = Column('unit_id', Integer, ForeignKey('unit.id')) unit = relationship("Unit", backref=backref('users')) def to_dict(self): return dict(id=self.id, phone_number=self.phone_number, password=self.password, nickname=self.nickname, headpic=self.headpic, register_time=self.register_time.strftime('%Y-%m-%d %H:%M:%S'), user_admin=self.user_admin, rc_token=self.rc_token, unit_id=self.unit_id, device_token=self.device_token, ) class Group(Base): __tablename__ = 'groups' id = Column('id', Integer, primary_key=True) name = Column('name', String(100), index=True) address = Column('address', String(100), index=True, nullable=True) contact_person = Column('contactperson', String(30), nullable=True) contact_number = Column('contactnumber', String(30), nullable=True) unit_id = Column('unit_id', Integer, ForeignKey('unit.id')) unit = relationship('Unit', backref=backref('groups')) class Monitor(Base): __tablename__ = 'monitor' id = Column('id', Integer, primary_key=True) u_id = Column('sn_num', String(10), index=True) phone_num = Column('phone_num', String(20), index=True, nullable=True) name = Column('name', String(40), index=True, nullable=True) position = Column('position', String(40), nullable=True) join_time = Column('join_time', DateTime, index=True, nullable=True) group_id = Column('group_id', Integer, ForeignKey('groups.id')) group = relationship("Group", backref=backref('monitors')) longitude = Column('longitude', DECIMAL(12, 9), default=31.000000) latitude = Column('latitude', DECIMAL(12, 9), default=121.000000) def to_dict(self): unit_id = self.group.unit_id return dict(id=self.id, u_id=self.u_id, phone_num=self.phone_num, name=self.name, position=self.position, join_time=self.join_time.strftime('%Y-%m-%d %H:%M:%S'), unit_id=unit_id, longitude=str(self.longitude), latitude=str(self.latitude)) class Unit(Base): __tablename__ = 'unit' id = Column('id', Integer, primary_key=True) name = Column('name', String(100), index=True, nullable=True) address = Column('address', String(100), index=True, nullable=True) contact_person = Column('contactperson', String(30), index=True, nullable=True) contact_number = Column('contactnumber', String(30), nullable=True) device_operation_password = Column('device_operation_password', String(4), nullable=True) rc_group_id = Column('rc_group_id', String(50), index=True, nullable=True) rc_group_name = Column('rc_group_name', String(50), index=True, nullable=True) longitude = Column('longitude', DECIMAL(12, 9), nullable=True) latitude = Column('latitude', DECIMAL(12, 9), nullable=True) active = Column('active', SmallInteger, index=True, default=0) def to_dict(self): return dict(id=self.id, name=self.name, address=self.address, contact_person=self.contact_person, contact_number=self.contact_number, device_operation_password=self.device_operation_password, rc_group_id=self.rc_group_id, rc_group_name=self.rc_group_name, longitude=str(self.longitude), latitude=str(self.latitude), active=self.active) db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine)) Base.query = db_session.query_property() def old_sql_2_redis(): redis_store.flushdb() units = Unit.query.all() [redis_store.rpush('units', json.dumps(unit.to_dict())) for unit in units] users = User.query.all() [redis_store.rpush('users', json.dumps(user.to_dict())) for user in users] monitors = Monitor.query.all() [redis_store.rpush('monitors', json.dumps(monitor.to_dict())) for monitor in monitors] if __name__ == '__main__': old_sql_2_redis()
把原来的数据库复制到本地redis了,看查看里面的元素。比如user数据,直接建一个user的list,每个appened其json格式的数据就可以了。主要注意点就是,如果新版本的表中没有的字段,就不要写入的redis了。
第二步就是把本地redis里面的数据,放到新的数据库上。这边要注意以下,把需要修改的地方要标示出来,可能加了其他字段,这些字段没有默认值的话,要自己添加上。过程也比较简单。
# coding:utf-8 from sqlalchemy import create_engine, ForeignKey, Column, Integer, String, Text, DateTime, Boolean, and_, or_,\ SmallInteger, func, Numeric, select, Float, Table, TIMESTAMP, DECIMAL, desc from sqlalchemy.orm import relationship, backref, sessionmaker, scoped_session from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method, Comparator from sqlalchemy import event import redis import json import datetime import uuid mysql_info = "mysql://username:password@ip_address:3306/database_name?charset=utf8" redis_store = redis.Redis(host='127.0.0.1', port=6380, password='password', db=5) engine = create_engine(mysql_info, pool_recycle=7200) Base = declarative_base() class User(Base): __tablename__ = 'user' id = Column('id', Integer, primary_key=True) phone_number = Column('phone_number', String(11), index=True) password = Column('password', String(30)) nickname = Column('nickname', String(30), index=True, nullable=True) headpic = Column('headpic', String(100), nullable=True) register_time = Column('register_time', DateTime, index=True, default=datetime.datetime.now) user_admin = Column('user_admin', SmallInteger, index=True, default=0) hidden_user = Column('hidden_user', SmallInteger, index=True, default=0) rc_token = Column('rc_token', String(100), nullable=True) device_token = Column('device_token', String(100), unique=True, nullable=True) unit_id = Column('unit_id', Integer, ForeignKey('unit.id')) unit = relationship('Unit', backref=backref('users')) class Monitor(Base): __tablename__ = 'monitor' id = Column('id', Integer, primary_key=True) # device_type 1代表灭弧 2代表电气火灾 device_type = Column('device_type', SmallInteger, index=True, default=1) u_id = Column('sn_num', String(10), index=True) phone_num = Column('phone_num', String(20), index=True, nullable=True) name = Column('name', String(40), index=True) position = Column('position', String(40), nullable=True) join_time = Column('join_time', DateTime, index=True) longitude = Column('longitude', DECIMAL(12, 9), default=31.000000) latitude = Column('latitude', DECIMAL(12, 9), default=121.000000) unit_id = Column('unit_id', Integer, ForeignKey('unit.id')) class Unit(Base): __tablename__ = 'unit' id = Column('id', Integer, primary_key=True) name = Column('name', String(100), index=True) address = Column('address', String(100), index=True, nullable=True) contact_person = Column('contactperson', String(30), nullable=True) contact_number = Column('contactnumber', String(30), nullable=True) device_operation_password = Column(') rc_group_id = Column('rc_group_id', String(36), default=str(uuid.uuid1())) rc_group_name = Column('rc_group_name', String(50), nullable=True) longitude = Column('longitude', DECIMAL(12, 9), default=31.000000) latitude = Column('latitude', DECIMAL(12, 9), default=121.000000) active = Column('active', SmallInteger, index=True, default=0) is_group = Column('is_group', SmallInteger, index=True, default=0) parent_id = Column('parent_id', Integer, ForeignKey('unit.id')) db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine)) Base.query = db_session.query_property() def redis_2_new_sql(): units_json = redis_store.lrange('units', 0, -1) units = [Unit(is_group=0, parent_id=None, **json.loads(unit_json)) for unit_json in units_json] [db_session.add(unit) for unit in units] try: db_session.commit() except Exception as e: print e db_session.rollback() return users_json = redis_store.lrange('users', 0, -1) users = [User(hidden_user=0, **json.loads(uer_json)) for uer_json in users_json] [db_session.add(user) for user in users] try: db_session.commit() except Exception as e: print e db_session.rollback() return monitors_json = redis_store.lrange('monitors', 0, -1) monitors = [Monitor(**json.loads(monitor_json)) for monitor_json in monitors_json] [db_session.add(monitor) for monitor in monitors] try: db_session.commit() except Exception as e: print e db_session.rollback() return if __name__ == '__main__': redis_2_new_sql()
整个过程相当简单,需要注意的就是,前后顺序,因为user和monitor都有一个外键指向unit,所以要先恢复unit表,这样就不会出错了。
看来以后我有新方法搬迁数据库了。
利用redis协助mysql数据库搬迁的更多相关文章
- 用Redis作为Mysql数据库的缓存【转】
用Redis作Mysql数据库缓存,必须解决2个问题.首先,应该确定用何种数据结构存储来自Mysql的数据:在确定数据结构之后,还要考虑用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是 ...
- 利用oneproxy部署mysql数据库的读写分离
实验系统:CentOS 6.6_x86_64 实验前提:防火墙和selinux都关闭 实验说明:本实验共有4台主机,IP分配如拓扑 实验软件:mariadb-10.0.20 oneproxy-rhel ...
- 利用xtrabackup备份mysql数据库
利用xtrabackup备份mysql数据库 一.安装1.直接下载二进制文件wget http://www.percona.com/downloads/XtraBackup/XtraBackup-2. ...
- 用Redis作Mysql数据库缓存
使用redis作mysql数据库缓存时,需要考虑两个问题: 1.确定用何种数据结构存储来自Mysql的数据; 2.在确定数据结构之后,用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是按 ...
- redis(二)--用Redis作MySQL数据库缓存
用Redis作MySQL数据库缓存,必须解决2个问题.首先,应该确定用何种数据结构存储来自mysql的数据:在确定数据结构之后,还要考虑用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是 ...
- 利用Java进行MySql数据库的导入和导出
利用Java来进行Mysql数据库的导入和导出的总体思想是通过Java来调用命令窗口执行相应的命令. MySql导出数据库的命令如下: mysqldump -uusername -ppassword ...
- node.js利用express连接mysql数据库
我们创建一个mysql.js (好像大神们,称呼这叫一个模块,然后暴露一个接口)用来连接数据库 var connction ={}; connction.mysql = { host:"lo ...
- 利用NHibernate与MySQL数据库交互
本文章使用Visual Studio作为开发工具,并建立在已经安装MySQL数据库的前提. NHibernate是一个面向.NET环境的对象/关系数据库映射工具.官网:http://nhibernat ...
- 利用Python操作MySQL数据库
前言 在工作中,我们需要经常对数据库进行操作,比如 Oracle.MySQL.SQL Sever 等,今天我们就学习如何利用Python来操作 MySQL 数据库. 本人环境:Python 3.7.0 ...
随机推荐
- CentOS安装MySQL问题汇总
遇到的错误 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) denied for ...
- poj 1819 Disks
http://poj.org/problem?id=1819 #include <cstdio> #include <cstring> #include <cmath&g ...
- CSS之Position详解
CSS的很多其他属性大多容易理解,比如字体,文本,背景等.有些CSS书籍也会对这些简单的属性进行大张旗鼓的介绍,而偏偏忽略了对一些难缠的属性讲解,有避重就轻的嫌疑.CSS中主要难以理解的属性包括盒型结 ...
- PCB敷铜小结
有人说加大敷铜可以加大散热面,其实,对于此我不以为然.我说过铜是一种散热吸热快的金属,如果加大散热面要靠加大敷铜的面积的话,那就没有必要给很多的器件加热片了,我想大家对于计算机都颇有心得,一定攒过电脑 ...
- MCS-51单片机存储器结构
MCS-51的存储器可分为四类: 程序存储器 一个微处理器能够聪明地执行某种任务,除了它们强大的硬件外,还需要它们运行的软件,其实微处理器并不聪明,它们只是完全按照人们预先编写的程序而执行之.那么设 ...
- 天底下最简单的QT画图板,就一个类,60行代码
简单直观.但是我有个问题是,这实际上不是在绘制直线,而是几千几万个超级短的“直线”,这样会不会效率很低呢? 注意,每次绘制的时候,需要一支笔,这支笔需要设置颜色和宽度(就像我们平时写字也要稍微挑一下笔 ...
- windows 查看文件被哪个进程占用
经常当我们删除文件时,有时会提示[操作无法完成,因为文件已在另一个程序中打开,请关闭该文件并重试],到底是哪些程序呢? 有时候一个一个找真不是办法,已经被这个问题折磨很久了,今天下决心要把它解决,找到 ...
- HDU_1009——老鼠的交易,性价比排序,最大化收益
Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats guarding th ...
- 算法导论(第三版)Problems2(归并插入排序、数列逆序计算)
讨论内容不说明,仅提供相应的程序. 2.1:归并插入排序θ(nlgn) void mergeInsertionSort(int a[], int l, int r, int k) { int m; & ...
- hadoop2.2.0伪分布模式64位安装
hadoop2.2.0伪分布模式64位安装用到的软件:jdk-6u45-linux-x64.bin,hadoop-2.2.0.x86_64.tar.gz 修改主机名vim /etc/sysconfig ...