python练习册第二题

题目

将 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

廖大的教程

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行不通,cdsitepackage文件夹,使用easy_install又可以了,就记录一下。

既然用了,总要学点东西。pip最早应该是Linux里的,之前win用的都是easy_install。不过现在easy_installpip都是用来下载安装Python一个公共资源库PyPI 的相关资源包的pipeasy_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)。现在就没问题了。

猜你喜欢

转载自www.cnblogs.com/ChanWunsam/p/10018282.html