在云服务器上安装MySQL (MariaDB) 数据库并与Python连接和互动

诸神缄默不语-个人CSDN博文目录

本文介绍如何在云服务器(CentOS)上安装MySQL数据库(其实是MariaDB数据库,但是当成MySQL用也没什么问题),并用pymysql或peewee与原生Python代码进行互动,或用Flask-SQLAlchemy与Flask进行互动。

之所以不直接租个数据库是因为暂时来说服务器的储存空间还够用。

关于pymysql和Flask-SQLAlchemy的选择,可以参考ChatGPT-4的回答:

如果你正在使用Flask来开发一个Web应用,Flask-SQLAlchemy是一个很好的选择,它提供了更高级的数据库抽象,支持更复杂的ORM模式,并且与Flask紧密集成。但是如果你的需求比较简单,或者你更喜欢直接使用SQL语句,那么pymysql就足够好了。

1. CentOS云服务器安装MySQL数据库

我记得有的镜像好像是默认安装MySQL的,但反正我没有。
可以用这个命令查证一下:mysql --version
没安装的话就会返回这个信息:bash: mysql: command not found
安装后就会返回类似的信息:mysql Ver 8.0.26 for Linux on x86_64 (Source distribution)

root用户运行:yum install mysql
(如果用普通用户运行,就会报这个信息:Error: This command has to be run with superuser privileges (under the root user on most systems).

以下流程也都用root用户运行:

yum install mysql-server
systemctl start mysqld
systemctl enable mysqld

安装服务器→启动→设置开启自启动(不过看介绍说好像这一条不太需要,因为MySQL默认开启)

查看MySQL的运行状态:systemctl status mysqld
在这里插入图片描述

注意接下来的步骤比较微妙:我的情况是mysqld的位置在/var/log/mysql/mysqld.log,这个文件的内容是:
在这里插入图片描述
这玩意居然是空密码开启的……别的教程里面都可以用sudo grep 'temporary password' /var/log/mysqld.log这个命令获取临时密码的。
据说这是因为服务器版本的问题。

总之我是空密码登录:mysql -u root -p

进入MySQL环境中就可以使用SQL语言来进行工作了(具体命令可以查看我之前写的博文:MySQL命令行速查手册(持续更新ing…)

exit或者quit退出MySQL环境。

2. PyMySQL包

PyMySQL包差不多就是直接用Python写SQL语言了。

官方GitHub项目:PyMySQL/PyMySQL: MySQL client library for Python
官方文档:Welcome to PyMySQL’s documentation! — PyMySQL 0.7.2 documentation

安装方式:pip install PyMySQL

with上下文管理器的示例代码(往表格中插入一条信息,查询这条信息):

import pymysql.cursors

# Connect to the database
connection = pymysql.connect(host='localhost',
                             user='New-Username',
                             password='New-Password',
                             db='New-DatabaseName',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

with connection:
    with connection.cursor() as cursor:
        # Create a new record
        sql = "INSERT INTO `users` (`phone_number`, `password`) VALUES (%s, %s)"
        cursor.execute(sql, (phone_number,password))

    # connection is not autocommit by default. So you must commit to save
    # your changes.
    connection.commit()

    with connection.cursor() as cursor:
        # Read a single record
        sql = "SELECT `id`, `password` FROM `users` WHERE `phone_number`=%s"
        cursor.execute(sql, (phone_number,))
        result = cursor.fetchone()
        print(result)

手动设置开关文件流的示例代码(往表格中插入一条信息):

import openpyxl
import pymysql.cursors

# Connect to the database
connection = pymysql.connect(host='localhost',
                             user='New-Username',
                             password='New-Password',
                             db='New-DatabaseName',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

cursor = connection.cursor()
    
cursor.execute("""
    INSERT INTO Papers (
    title, authors, summary, paper_url, publication_date, updated_date, is_legalAI
    ) VALUES (%s, %s, %s, %s, %s, %s, %s)
""", (title, authors, summary, paper_url, publication_date_str, updated_date_str, is_legalAI))

# 提交事务,保存到数据库
connection.commit()

# 关闭数据库连接
cursor.close()
connection.close()

执行查询命令:

cursor.execute("SELECT * FROM Papers WHERE LOWER(title) = LOWER(%s)", (title,))
result = cursor.fetchone()

result返回的是一个样本,是元组或是字典(设置cursorclass=pymysql.cursors.DictCursor时。用列名提取属性值)

其他注意事项:

  1. 对于MySQL中DATE属性的列,从Python传入的字符串,如原始2001-06-07T14:40:04Z,可以通过这样的步骤进行转换:
    from datetime import datetime
    
    # 原始字符串
    date_string = "2001-06-07T14:40:04Z"
    
    # 将字符串转换为datetime对象
    dt = datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%SZ")
    
    # 将datetime对象格式化为MySQL可以接受的日期格式
    mysql_date = dt.strftime("%Y-%m-%d")
    
    ↑然后传入mysql_date这个对象就可以
  2. ↑这个代码只提取了日期部分,没有时间部分,因为数据库列是DATE类型,只能存储日期,不能存储时间。如果数据库列是DATETIME类型,可以存储日期和时间,那么可以使用strftime("%Y-%m-%d %H:%M:%S")来格式化datetime对象。
  3. 特殊功能实现
    1. 将字典插入数据库:
    import pymysql
    
    # 创建连接
    conn = pymysql.connect(host='your_host', user='your_username', password='your_password', db='your_db', charset='utf8')
    
    # 创建游标
    cursor = conn.cursor()
    
    data_dict = {
          
          "column1": "value1", "column2": "value2", "column3": "value3"}  # 你的字典数据
    
    table_name = "your_table"  # 你的表名
    
    keys = ', '.join(data_dict.keys())
    values = ', '.join(['%s'] * len(data_dict))
    
    sql = 'INSERT INTO {table} ({keys}) VALUES ({values})'.format(table=table_name, keys=keys, values=values)
    
    try:
        if cursor.execute(sql, tuple(data_dict.values())):
            print('Successful')
            conn.commit()
    except:
        print('Failed')
        conn.rollback()
    
    # 关闭游标和连接
    cursor.close()
    conn.close()
    
    1. 按照字典更新数据库:
    import pymysql
    
    # 创建连接
    conn = pymysql.connect(host='your_host', user='your_username', password='your_password', db='your_db', charset='utf8')
    
    # 创建游标
    cursor = conn.cursor()
    
    data_dict = {
          
          "column1": "new_value1", "column2": "new_value2"}  # 你的字典数据
    
    table_name = "your_table"  # 你的表名
    
    condition = "column3 = 'value3'"  # 更新的条件
    
    data = ', '.join([f"{
            
            k}=%s" for k in data_dict.keys()])
    
    sql = f'UPDATE {
            
            table_name} SET {
            
            data} WHERE {
            
            condition}'
    
    try:
        if cursor.execute(sql, tuple(data_dict.values())):
            print('Successful')
            conn.commit()
    except:
        print('Failed')
        conn.rollback()
    
    # 关闭游标和连接
    cursor.close()
    conn.close()
    
    1. 按照字典更新数据库,这个是where语句也是字符串格式,需要判断的条件。然后别的部分不用重复写:
    data = ', '.join([f"{
            
            k}=%s" for k in paper.keys()])
    
    values = tuple(paper.values()) + (paper["title"],)
    
    cursor.execute(f"""
        UPDATE Papers SET 
        {
            
            data}
        WHERE LOWER(title) = LOWER(%s)
    """, values)
    

3. Flask-SQLAlchemy包

官方GitHub项目:pallets-eco/flask-sqlalchemy: Adds SQLAlchemy support to Flask
官方速成教程:Quick Start — Flask-SQLAlchemy Documentation (3.0.x)

安装方式:pip install -U Flask-SQLAlchemy

注意Python 3+必须要安装pymysql,才能正常用Flask-SQLAlchemy,因为如果不用pymysql引擎,就会需要用MySQLdb这个包,但是这个包只支持Python 2。

在flask应用中导入:

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import sessionmaker

db=SQLAlchemy()
app.config["SQLALCHEMY_DATABASE_URI"]="mysql+pymysql://MySQL用户名:MySQL用户密码@localhost/database名"
#localhost是数据库的IP地址
db.init_app(app)

with app.app_context():
    db.create_all()  #也可以不用这句话,直接在该上下文中运行Flask-SQLAlchemy命令

db.Model类:每个db.Model就相当于一个table,会自动与数据库中实际存在的表相连,如果数据库中不存在会创建。关联方式是要么用__tablename__指定,要么根据db.Model类名来指定(如类名为User,默认表名就是user;类名为UserUsage,默认表名就是user_usage):
(这里多用了一个包:Werkzeug
官方文档:Werkzeug — Werkzeug Documentation (2.3.x)
安装方式:pip install Werkzeug
这个包我以后可能会专门写个介绍博文,现在就直接用就行)

from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash

import datetime

class User(UserMixin,db.Model):
    __tablename__='users'
    id=db.Column(db.Integer,primary_key=True)
    phone_number=db.Column(db.String,unique=True,nullable=False)
    nickname=db.Column(db.String)
    password=db.Column(db.String)
    email=db.Column(db.String)
    memo=db.Column(db.String)

    def set_password(self,password):
    	"""将password加密"""
        self.password=generate_password_hash(password)

    def check_password(self,password):
    	"""检查用户输入的密码加密后,是否与储存的密码相同"""
        return check_password_hash(self.password,password)

class ChatBotIO(db.Model):
    __tablename__='chatbot_io'
    id=db.Column(db.Integer,primary_key=True)
    user_id=db.Column(db.Integer,nullable=False)
    phone_number=db.Column(db.String,unique=True,nullable=False)
    service_name=db.Column(db.String,nullable=False)
    user_input=db.Column(db.String)
    system_output=db.Column(db.String)
    now_time=db.Column(db.DateTime,default=datetime.datetime.now)

class UserUsage(db.Model):  #用户的每日使用数量
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    date = db.Column(db.Date, default=datetime.datetime.now)
    dialogues = db.Column(db.Integer, default=0)
    tokens = db.Column(db.Integer, default=0)
  1. 创建一个样本对象:
    1. 常规写法(一次性初始化所有属性):
    today = datetime.datetime.now().date()
    usage = UserUsage(user_id=current_user.id, date=today)
    
    1. 特殊写法
    user=User(phone_number=phone_number)
    user.set_password(password)
    
  2. 将样本增加到数据库中:
db.session.add(user)
db.session.commit()
  1. 将样本从数据库中删除:
user = User.query.filter_by(phone_number='13451245454').first()
if user:
    # 删除用户
    db.session.delete(user)
    db.session.commit()
  1. 查询样本:
    user=User.query.filter_by(phone_number=form.phone.data).first()(如果不存在,将返回None

4. 其他Python包

1 peewee包

peewee包官方文档:peewee — peewee 3.16.2 documentation

2 SQLAlchemy包

SQLAlchemy包官方文档:SQLAlchemy - The Database Toolkit for Python

3 MySQL Connector/Python包

这是MySQL官方提供的。

pypi主页:https://pypi.org/project/mysql-connector-python/

4 SQLObject包

SQLObject包官方文档:SQLObject — SQLObject 3.10.1 documentation

5. 本文撰写过程中参考的网络资料

  1. How To Install MySQL on CentOS 7 | DigitalOcean
  2. How to Start, Stop, and Restart MySQL Server - Hivelocity Hosting
  3. CentOS MySQL安装及问题解决_grep: /var/log/mysqld.log: no such file or directo_Charlie。的博客-CSDN博客
  4. 【MySQL入门】(五)Flask使用MySQL存储数据_flask mysql_DooDoo~的博客-CSDN博客
  5. python - ImportError: No module named MySQLdb - Stack Overflow
  6. Python 3 ImportError: No module named ‘ConfigParser’ - Stack Overflow
  7. flask博客项目阿里云ECS部署
  8. html - How to prevent the browser from asking for the favicon? - Stack Overflow:答案是没啥影响,不嫌弃就不去掉也行
  9. How To Redirect To Url In Python Flask – vegibit

猜你喜欢

转载自blog.csdn.net/PolarisRisingWar/article/details/130975217