目录
题目
将 0001 题生成的 200 个激活码(或者优惠券)保存到 MySQL 关系型数据库中。
解决思路
基本步骤应该是:读取文件 –> 解析字符 –> 打开数据库 –> 存入后关闭。其中涉及python操作mysql数据库的我还不是很熟悉。
py3.6我是用pymysql作为驱动的,语法基本上和廖大提到的mysql-connector差不多,个别地方需要有所改动。
pymysql操作数据库的基本套路就是连接数据库,连接数据库游标,再通过游标的execute
语句执行mysql操作。
解决代码
自觉写得好烂……只是应付题目就不要要求太高了吧。
import base64
import re
import pymysql
def parser(line):
return base64.b64decode(line).decode()
def re_split(s):
list = re.split(r'[\:\/]+', s)
dict = {
list[0]: list[1],
list[2]: list[3]
}
return dict
def connect():
conn = pymysql.connect(host='localhost', port=3306,db='test', user='***', password='***') # 根据实际填
cur = conn.cursor()
sql_create = "create table if not exists `coupon` (`id` varchar(20), `goods` varchar(20))"
# cur.execute(sql_create)
return cur, conn
def insert(cur, dict):
sql = 'insert into coupon (id, goods) values ({id}, {goods})'
cur.execute(sql.format(id=dict['id'], goods=dict['goods']))
if __name__ == '__main__':
cur, conn = connect()
with open('C:/Users/ChanWunsam/Desktop/coupon.txt', 'r') as fp:
for line in fp.readlines():
s = parser(line)
dict = re_split(s)
print(dict)
insert(cur, dict)
conn.commit() # 特别需要注意
conn.close()
别人的思路
这道题没有需求,我也不知道要怎样才好。这位大神估计是经历过实践的,把激活码的id、有效时间、所有者和激活码本身都存入进去了。emmm,我压根就不知道有这么多东西。
还有就是代码看上去确实赏心悦目,我个人是这么觉得的。默默学习了~
import base64
import re
from sqlalchemy import Column, String, DATE, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
database_info = {
'user': '',
'passwd': '',
'ip': '',
'port': '',
'database': ''
}
class Coupon(Base):
__tablename__ = 'coupon'
id = Column(String(200), primary_key=True)
deadline = Column(DATE)
userID = Column(String(200))
code = Column(String(200))
def make_connect(DB_info): # mapper
connect_str = 'mysql+pymysql://{user}:{passwd}@{ip}:{port}/{database}'.format_map(DB_info)
engine = create_engine(connect_str)
DBSession = sessionmaker(engine)
session = DBSession()
return session
def parse_coupon(c_code):
return base64.urlsafe_b64decode(c_code.encode('utf-8'))
def upload_to_database():
session = make_connect(database_info)
with open('coupon.txt', 'r') as file:
for line in file.readlines():
c_id = re.findall(r'.*/.*:(.*)\'', str(parse_coupon(line)))
session.add(Coupon(id=c_id.pop(), code=line))
session.commit()
session.close()
if __name__ == '__main__':
upload_to_database()
关于sqlalchemy
There are three most important components in writing SQLAlchemy code:
- A Table that represents a table in a database.
- A mapper that maps a Python class to a table in a database.
- A class object that defines how a database record maps to a normal Python object.
Instead of having to write code for Table, mapper and the class object at different places, SQLAlchemy’s declarative allows a Table, a mapper and a class object to be defined at once in one class definition.
廖大的示例:
#第一步,导入SQLAlchemy,并初始化DBSession:
# 导入:
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# 创建对象的基类:
Base = declarative_base()
# 定义User对象:
class User(Base):
# 表的名字:
__tablename__ = 'user'
# 表的结构:
id = Column(String(20), primary_key=True)
name = Column(String(20))
# 初始化数据库连接:
engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')
# 创建DBSession类型:
DBSession = sessionmaker(bind=engine)
#以上代码完成SQLAlchemy的初始化和具体每个表的class定义。如果有多个表,就继续定义其他class,例如School:
class School(Base):
__tablename__ = 'school'
id = ...
name = ...
#由于有了ORM,我们向数据库表中添加一行记录,可以视为添加一个User对象:
# 创建session对象:
session = DBSession()
# 创建新User对象:
new_user = User(id='5', name='Bob')
# 添加到session:
session.add(new_user)
# 提交即保存到数据库:
session.commit()
# 关闭session:
session.close()
基本和官网示例差不多,就是官网的看得一愣一愣的。
easy_install
今天本来想重现下大神的代码,发现包还没装。不知什么原因pip install
行不通,cd
到sitepackage
文件夹,使用easy_install
又可以了,就记录一下。
既然用了,总要学点东西。pip
最早应该是Linux里的,之前win用的都是easy_install
。不过现在easy_install
和pip
都是用来下载安装Python一个公共资源库PyPI
的相关资源包的,pip
是easy_install
的改进版,提供更好的提示信息,删除package等功能。老版本的python中只有easy_install
,没有pip
。
复现发现的问题
在复现大神代码时候,发现报错pymysql.err.ProgrammingError: (1146, "Table 'test.coupon' doesn't exist")
,表没有创建。上网查了一下,有人问一模一样的问题,是少了一个语句Base.metadata.create_all(engine)
.
session.add()
是建立在数据库中已经有对应table的基础上了,所以需要先对数据库进行表的建立:Base.metadata.create_all(engine)
。现在就没问题了。