from optparse import OptionParser
import pymysql
class TransferMoney(object):
def __init__(self, conn):
self.conn = conn
def transfer(self, source_acctid, target_acctid, money):
"""转账函数"""
try:
# 判断账户是否存在?
self.check_acct_available(source_acctid)
self.check_acct_available(target_acctid)
self.has_enough_money(source_acctid, money)
# 001: 1000 002: 500
# 001: 1000 002: 500
self.reduce_money(source_acctid, money)
self.add_money(target_acctid, money)
self.conn.commit()
except Exception as e:
# 撤销数据库的执行
self.conn.rollback()
raise e
def check_acct_available(self, acctid):
"""检测账户是否存在?"""
cur = self.conn.cursor()
try:
# 查询账户名为acctid的详细信息
select_sql = 'select * from account where accid=%s;' % (acctid)
cur.execute(select_sql)
print("execute sql:%s" % (select_sql))
res = cur.fetchall()
if len(res) != 1:
raise Exception("帐号%s不存在" % (acctid))
finally:
cur.close()
def has_enough_money(self, acctid, money):
"""检测账户是否有足够的钱"""
cur = self.conn.cursor()
try:
select_sql = 'select money from account where accid=%s' %(acctid)
cur.execute(select_sql)
print('has_enough_money sql: %s' %(select_sql))
res = cur.fetchall()
if res:
now_money = int(res[0][0])
if int(now_money) < int(money):
raise Exception("账户%s没有足够的钱,目前金额为 %d" %(acctid, now_money))
finally:
cur.close()
def reduce_money(self, acctid, money):
"""给其他账户进行转账操作"""
cur = conn.cursor()
try:
update_sqli = 'update account set money=money-%s where accid=%s' %(money, acctid)
cur.execute(update_sqli)
print('reduce_money sql:%s' %(update_sqli))
except Exception as e:
print("reduce money failed:",e)
finally:
cur.close()
def add_money(self, acctid, money):
cur = conn.cursor()
try:
update_sqli = 'update account set money=money+%s where accid=%s' % (money, acctid)
cur.execute(update_sqli)
print('add_money sql:%s' % (update_sqli))
except Exception as e:
print("add money failed:",e)
finally:
cur.close()
if __name__ == "__main__":
##连接数据库
print()
conn = pymysql.connect(
host='172.25.254.41', user='root', passwd='redhat',
db='bank', charset='utf8')
USAGE = "command [OPTION....]"
parser = OptionParser(USAGE) ##可以替代getopt的一个模块,用来处理命令行的模块
# 转账帮助的命令加解释:
# -s: type:类型, dest: 传递的值赋值的变量名, help:帮助, default: 默认值
parser.add_option('-s', type=int, dest='srcid', help="原账户id", default=610001)
parser.add_option('-d', type=int, dest='destid', help='目标账户id', default=610002)
parser.add_option('-m', type=int, dest='money', help='转账金额', default=500)
# 解析接收的属性值
option, args = parser.parse_args()
source_acctid = option.srcid
target_acctid = option.destid
money = option.money
trans_money = TransferMoney(conn)
try:
print(source_acctid, target_acctid, money)
trans_money.transfer(source_acctid, target_acctid, money)
except Exception as e:
print("转账出现问题:", e)
finally:
conn.commit()
conn.close()
测试:
(python3) [kiosk@foundation41 W]$ python3 银行转账.py -help
Usage: command [OPTION….]
Options:
-h, –help show this help message and exit
-s SRCID 原账户id
-d DESTID 目标账户id
-m MONEY 转账金额
1
数据库:
MariaDB [bank]> select * from account;
+——–+——-+
| accid | money |
+——–+——-+
| NULL | NULL |
| NULL | NULL |
| 610002 | 1020 |
| 610001 | 0 |
+——–+——-+
(python3) [kiosk@foundation41 W]$ python3 银行转账.py -s 610001 -d 610002 -m 500
610001 610002 500
execute sql:select * from account where accid=610001;
execute sql:select * from account where accid=610002;
has_enough_money sql: select money from account where accid=610001
转账出现问题: 账户610001没有足够的钱,目前金额为 0
2
(python3) [kiosk@foundation41 W]$ python3 银行转账.py -s 610002 -d 610001 -m 500
610002 610001 500
execute sql:select * from account where accid=610002;
execute sql:select * from account where accid=610001;
has_enough_money sql: select money from account where accid=610002
reduce_money sql:update account set money=money-500 where accid=610002
add_money sql:update account set money=money+500 where accid=610001
数据库:
MariaDB [bank]> select * from account;
+——–+——-+
| accid | money |
+——–+——-+
| NULL | NULL |
| NULL | NULL |
| 610002 | 520 |
| 610001 | 500 |