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
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:[email protected]: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)
。現在就沒問題了。