正常的pymysql当然问题不大,但是我个人还是建议:sqlalchemy! 因为他更能让我们把精力放在表单设计上,而不执着于代码本身了.
(-----版权所有。未经作者书面同意,不得转载或用于任何商业用途!----)
CREATE TABLE match_info (
id INT PRIMARY KEY,
home_team VARCHAR(30),
full_score VARCHAR(8),
half_score VARCHAR(8),
away_team VARCHAR(30),
match_time DATETIME,
#比赛时间如 '2023-12-15 14:30:00'包括年、月、日、时、分、秒
league VARCHAR(10),
corners VARCHAR(10),
zhuangtai INT,
#状态,1(完成收录) 0(未开始) -1(数据待补)
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
#修改时间
);
from datetime import datetime
from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, DateTime
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import sessionmaker
class MatchInfoCRUD:
# 初始化类并建立数据库连接
def __init__(self):
self.db_uri = 'mysql+pymysql://user:password@localhost/mydatabase' #填入自己的信息:user:password@localhost/mydatabase
self.engine = create_engine(self.db_uri) # 使用数据库URI创建引擎
self.metadata = MetaData() # 元数据对象用于收集表对象
# 定义match_info表结构
self.match_info = Table('match_info', self.metadata,
Column('id', Integer, primary_key=True), # 主键不自增
Column('zhuangtai', Integer), # 整型状态列
Column('league', String(10)), # 长度为10的字符串类型的联赛列
Column('match_time', DateTime), # 日期时间类型的比赛时间列
Column('home_team', String(30)), # 长度为30的字符串类型的主队列
Column('full_score', String(8)), # 长度为8的字符串类型的全场比分列
Column('half_score', String(8)), # 长度为8的字符串类型的半场比分列
Column('away_team', String(30)), # 长度为30的字符串类型的客队列
Column('corners', String(10)), # 长度为10的字符串类型的角球数列
)
self.metadata.create_all(self.engine) # 在数据库中创建表
self.Session = sessionmaker(bind=self.engine) # 创建与数据库会话的会话工厂
# 创建新的比赛记录
def create_match(self, match_data):
session = self.Session() # 开启新的会话
try:
# 创建插入对象并插入数据
insert_object = self.match_info.insert().values(match_data)
session.execute(insert_object) # 执行插入操作
session.commit() # 提交事务
print("数据插入成功。")
except SQLAlchemyError as e: # 捕获并处理SQLAlchemy异常
print(f"插入数据时出现问题: {e}")
finally:
session.close() # 关闭会话
# 读取比赛记录
def read_match(self, match_id):
session = self.Session() # 开启新的会话
try:
query = session.query(self.match_info).filter_by(id=match_id) # 创建查询对象
match = query.first() # 获取查询结果的第一条记录
if match:
return match # 返回那条记录
else:
return None # 如果没找到记录,返回None
except SQLAlchemyError as e:
print(f"读取数据时出现问题: {e}")
finally:
session.close() # 关闭会话
# 更新比赛记录
def update_match(self, match_id, update_data):
session = self.Session() # 开启新的会话
try:
query = session.query(self.match_info).filter_by(id=match_id) # 创建查询对象
query.update(update_data) # 执行更新操作
session.commit() # 提交事务
print("数据更新成功。")
except SQLAlchemyError as e:
print(f"更新数据时出现问题: {e}")
finally:
session.close() # 关闭会话
# 删除比赛记录
def delete_match(self, match_id):
session = self.Session() # 开启新的会话
try:
query = session.query(self.match_info).filter_by(id=match_id) # 创建查询对象
match = query.first() # 获取查询结果的第一条记录
if match:
query.delete() # 如果找到记录则执行删除操作
session.commit() # 提交事务
print("数据删除成功。")
else:
print("未找到相应比赛。")
except SQLAlchemyError as e:
print(f"删除数据时出现问题: {e}")
finally:
session.close() # 关闭会话
# 创建MatchInfoCRUD的一个实例
crud = MatchInfoCRUD()
# 创建并插入新的比赛记录
match_data = {
'id': 1,
'zhuangtai': 1,
'league': '联赛数据',
'match_time': datetime(2023, 12, 15, 14, 30),
'home_team': 'Team A',
'full_score': '2-1',
'half_score': '1-0',
'away_team': 'Team B',
'corners': '5-4',
}
crud.create_match(match_data)
# 读取id为1的比赛记录
match_record = crud.read_match(1)
if match_record:
print(f"读取到比赛记录: {match_record}")
else:
print("没有找到对应的比赛记录。")
这里是4个基本属性,增删改查!!! 直接调用就好了...
潜在改进点,往下看
from datetime import datetime
from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import sessionmaker, scoped_session
# 定义基类
Base = declarative_base()
# 定义 MatchInfo ORM 模型
class MatchInfo(Base):
__tablename__ = 'match_info'
id = Column(Integer, primary_key=True)
home_team = Column(String(30))
full_score = Column(String(8))
half_score = Column(String(8))
away_team = Column(String(30))
match_time = Column(DateTime)
league = Column(String(10))
corners = Column(String(10))
zhuangtai = Column(Integer)
created_time = Column(DateTime, default=datetime.now)
updated_time = Column(DateTime, default=datetime.now, onupdate=datetime.now)
# MatchInfoCRUD 类使用 ORM 模型和会话管理
class MatchInfoCRUD:
def __init__(self):
self.db_uri = 'mysql+pymysql://user:password@localhost/mydatabase'
self.engine = create_engine(self.db_uri)
Base.metadata.create_all(self.engine)
self.Session = scoped_session(sessionmaker(bind=self.engine))
def create_match(self, match_data):
"""创建新的比赛记录"""
try:
match = MatchInfo(**match_data)
self.Session.add(match)
self.Session.commit()
print("数据插入成功。")
except SQLAlchemyError as e:
self.Session.rollback()
print(f"插入数据时出现问题: {e}")
finally:
self.Session.remove()
def read_match(self, match_id):
"""读取比赛记录"""
try:
match = self.Session.query(MatchInfo).get(match_id)
return match
except SQLAlchemyError as e:
print(f"读取数据时出现问题: {e}")
finally:
self.Session.remove()
def update_match(self, match_id, update_data):
"""更新比赛记录"""
try:
match = self.Session.query(MatchInfo).get(match_id)
for key, value in update_data.items():
setattr(match, key, value)
self.Session.commit()
print("数据更新成功。")
except SQLAlchemyError as e:
self.Session.rollback()
print(f"更新数据时出现问题: {e}")
finally:
self.Session.remove()
def delete_match(self, match_id):
"""删除比赛记录"""
try:
match = self.Session.query(MatchInfo).get(match_id)
if match:
self.Session.delete(match)
self.Session.commit()
print("数据删除成功。")
else:
print("未找到相应比赛记录。")
except SQLAlchemyError as e:
self.Session.rollback()
print(f"删除数据时出现问题: {e}")
finally:
self.Session.remove()
接下来对提供的MatchInfoCRUD类进行几个关键方面的优化,包括封装会话管理、优化查询处理,以及使用 SQLAlchemy ORM 更优雅地定义和交互数据库模型。这里需要使用 SQLAlchemy 的声明式基类declarative_base来简化模型定义,以及使用上下文管理器来自动化会话的生命周期管理。
from datetime import datetime
from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import sessionmaker, scoped_session
# 使用declarative_base创建ORM模型的基类
Base = declarative_base()
# 定义MatchInfo ORM模型
class MatchInfo(Base):
__tablename__ = 'match_info'
id = Column(Integer, primary_key=True)
zhuangtai = Column(Integer)
league = Column(String(10))
match_time = Column(DateTime)
home_team = Column(String(30))
full_score = Column(String(8))
half_score = Column(String(8))
away_team = Column(String(30))
corners = Column(String(10))
created_time = Column(DateTime)
updated_time = Column(DateTime)
# 自定义上下文管理器,管理数据库会话的生命周期
class DBSessionManager:
def __init__(self, db_uri):
self.engine = create_engine(db_uri)
self.Session = scoped_session(sessionmaker(bind=self.engine, autocommit=False, autoflush=False))
def __enter__(self):
self.session = self.Session()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.session.close()
class MatchInfoCRUD:
# 初始化类并建立数据库连接
def __init__(self, db_uri):
self.db_manager = DBSessionManager(db_uri)
Base.metadata.create_all(self.db_manager.engine)
# 创建新的比赛记录
def create_match(self, match_data):
with self.db_manager as db:
try:
match = MatchInfo(**match_data)
db.session.add(match)
db.session.commit()
print("数据插入成功。")
except SQLAlchemyError as e:
db.session.rollback()
print(f"插入数据时出现了问题: {e}")
# 查询等其他方法同理可以通过db_manager动态管理会话
# 使用新的CRUD接口进行操作
db_uri = 'mysql+pymysql://user:password@localhost/mydatabase' # 请填入数据库URI
crud = MatchInfoCRUD(db_uri)
match_data = {
'id': 1,
'zhuangtai': 1,
'league': '联赛数据',
'match_time': datetime(2023, 12, 15, 14, 30),
'home_team': 'Team A',
'full_score': '2-1',
'half_score': '1-0',
'away_team': 'Team B',
'corners': '5-4',
'created_time': datetime.now(),
'updated_time': datetime.now(),
}
crud.create_match(match_data)
# 后续其他增删改查操作可以类似地实现
(-----版权所有。未经作者书面同意,不得转载或用于任何商业用途!----)