Python入门实战:数据库连接与操作

191 阅读8分钟

1.背景介绍

Python是一种高级编程语言,可以用于解决各种各样的问题。其中,在数据分析、机器学习、科学计算等领域,Python的应用也越来越广泛。为了提高数据处理效率,数据存储成本和管理难度降低,越来越多的公司开始采用NoSQL(Not Only SQL)或者NewSQL作为分布式数据库系统。这些新型的数据库系统不仅支持传统关系数据库的SQL查询功能,还提供了非常丰富的查询功能,如图数据库、文档数据库等。由于这些数据库系统已经具有海量数据存储、强大的查询功能,因此,很多公司更倾向于使用这些数据库系统进行数据分析、业务决策。然而,对于Python开发者来说,使用这些数据库系统可能比较困难,因为需要掌握不同的API接口及查询语法。因此,本文将介绍如何使用Python连接和操作关系数据库和非关系数据库,包括MySQL、PostgreSQL、MongoDB等常用开源数据库系统。本文假设读者对Python有一定了解,并且了解相关数据库知识。文章结尾会给出参考资料,读者可以从中获取更多有关Python的资源。

2.核心概念与联系

首先,我们要清楚地认识一下关系数据库、非关系数据库、SQL、NoSQL和NewSQL之间的区别。

关系数据库(Relational Databases),又称为RDBMS(Relational DataBase Management System),顾名思义,就是关系型数据库。关系数据库存储的是结构化的数据,它的数据表由关系模式组成,关系模式是用来定义一个数据库表的数据结构的描述语言。关系数据库中的数据以行和列的方式来存储,每行记录代表一条信息,每列属性表示相应的信息内容。关系数据库利用SQL语言对数据进行查询,并通过一定的规则保证数据的一致性。关系数据库的优点是查询速度快,数据安全,数据组织较为容易理解。但是,当数据量越来越大时,关系数据库的性能可能会下降。

非关系数据库(NoSQL databases),主要包括键-值存储、文档存储、图形数据库、列存储等。非关系数据库没有固定的表结构,其底层数据结构可以是文档型、键-值型、列存储或图形数据库。非关系数据库通常能够应对高速写入、大规模数据访问的需求。一般来说,非关系数据库无法提供完整的ACID特性,但可以通过事务机制提供可靠的写入。非关系数据库可以极大地扩展业务量和性能,适合于复杂的多变业务场景。

SQL(Structured Query Language),是一种数据库查询语言。关系数据库管理系统(RDBMS)通常都内置了SQL语言,是非关系数据库的基础。关系数据库系统中的数据是通过SQL语句进行查询、修改、删除的。SQL的灵活性使得关系数据库系统能够处理复杂的查询,并且具备良好的容错性和性能。然而,SQL只限于关系数据库系统,对于非关系数据库系统,则需要另一种查询语言——NoSQL语言。

NoSQL(Not only SQL),是指非关系型数据库。NoSQL数据库一般被称为NoSQL或NoSQL数据库系统。NoSQL不依赖于SQL或基于SQL的特定语法,能够存储非结构化和半结构化的数据,如文档、日志、图像、视频等。NoSQL数据库系统不需要预先设计数据库的模式,而是直接插入、读取、更新和删除数据,这意味着它可以在执行查询之前不需要提前定义数据结构。NoSQL数据库能够快速响应,并且可以利用分布式集群结构实现高可用性。NoSQL数据库目前流行的有MongoDB、Couchbase、Redis等。

NewSQL(Next Generation SQL),是对传统数据库系统的一次革命。NewSQL数据库系统既保留了传统关系数据库的最佳特性,同时兼顾了非关系数据库和传统关系数据库的优点。NewSQL数据库的基本思想是在关系数据库的基础上,融合了多种非关系数据库的优点。比如,NewSQL数据库可以将数据以列存放到硬盘设备中,进一步提升查询性能;也可以将多个关系数据库的表关联起来,提供统一的视图;还可以通过计算引擎自动处理查询计划,通过快速缓存提高查询响应速度。但是,NewSQL数据库的普及仍然存在巨大挑战,尤其是涉及大量数据时。

总之,关系数据库是最传统的数据库系统,它以行和列的形式存储数据,支持SQL语言,支持ACID特性。然而,随着数据量的增长,关系数据库面临性能瓶颈,无法满足快速响应的需求。所以,非关系数据库就应运而生了,它对比关系数据库更侧重于快速响应能力。但是,非关系数据库没有固定的数据模型,只能存储非结构化和半结构化的数据。因此,对于某些特定的查询任务,关系数据库和非关系数据库可以组合使用。

3.核心算法原理和具体操作步骤以及数学模型公式详细讲解

操作关系数据库

MySQL数据库的连接与操作

我们可以使用pymysql模块连接MySQL数据库。以下是一个例子:

import pymysql

conn = pymysql.connect(host='localhost', port=3306, user='root', password='<PASSWORD>', db='testdb')

cursor = conn.cursor()

sql = "SELECT * FROM employee"
try:
    cursor.execute(sql)
    results = cursor.fetchall()
    for row in results:
        print(row[0], row[1]) #打印第一列和第二列
except Exception as e:
    print("Error: unable to fetch data", e)

cursor.close()
conn.close()

这个例子创建一个名为employee的表,然后进行连接操作,然后执行一条SQL命令,最后关闭连接。

如果想要创建表格,可以使用以下代码:

CREATE TABLE employees (
  id INT NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  age INT NOT NULL,
  PRIMARY KEY (id));

这个例子创建一个名为employees的表,包含三个字段,idnameageid是一个自增主键。我们可以使用INSERT INTO语句来插入数据。

sql = "INSERT INTO employees (name, age) VALUES (%s,%s)"
values = ('John Doe', 30)

try:
    cursor.execute(sql, values)
    conn.commit()
    print('Insert successful.')
except Exception as e:
    print("Error: unable to insert data", e)

    if conn:
        conn.rollback()

cursor.close()
conn.close()

这个例子向employees表中插入一行数据,包括姓名John Doe和年龄30

如果想要更新数据,可以使用UPDATE语句。

sql = "UPDATE employees SET age = %s WHERE name = %s"
values = (35, 'Jane Smith')

try:
    cursor.execute(sql, values)
    conn.commit()
    print('Update successful.')
except Exception as e:
    print("Error: unable to update data", e)

    if conn:
        conn.rollback()

cursor.close()
conn.close()

这个例子更新employees表中姓名为Jane Smith的年龄为35

如果想要删除数据,可以使用DELETE语句。

sql = "DELETE FROM employees WHERE name = %s"
value = ('John Doe',)

try:
    cursor.execute(sql, value)
    conn.commit()
    print('Delete successful.')
except Exception as e:
    print("Error: unable to delete data", e)

    if conn:
        conn.rollback()

cursor.close()
conn.close()

这个例子删除employees表中姓名为John Doe的这一行数据。

以上都是关系数据库的操作方式,当然了,实际生产环境中使用的数据库肯定不是这个,有很多工厂封装了数据库操作的包,方便我们使用。

PostgreSQL数据库的连接与操作

我们可以使用psycopg2模块连接PostgreSQL数据库。以下是一个例子:

import psycopg2

try:
    connection = psycopg2.connect(user="postgres",
                                  password="mysecretpassword",
                                  host="localhost",
                                  port="5432",
                                  database="testdb")

    cursor = connection.cursor()
    
    sql = "SELECT * FROM mytable;"
    cursor.execute(sql)
    result = cursor.fetchone()
    while result is not None:
        print(result)
        result = cursor.fetchone()
        
    # Modify table
    cursor.execute("""ALTER TABLE mytable ADD COLUMN address TEXT;""")
    connection.commit()
    
except (Exception, psycopg2.Error) as error :
    print ("Error while connecting to PostgreSQL", error)
    
finally:
    #closing database connection.
    if(connection):
        cursor.close()
        connection.close()
        print("PostgreSQL connection is closed")

这个例子创建了一个名为mytable的表格,然后进行连接操作,然后执行一条SQL命令,最后关闭连接。

如果想要创建表格,可以使用以下代码:

CREATE TABLE IF NOT EXISTS mytable (
  id SERIAL PRIMARY KEY,
  name VARCHAR(50),
  email VARCHAR(50) UNIQUE,
  phone VARCHAR(20) CHECK (phone ~ '^\\d{10}$'),
  address VARCHAR(50)
);

这个例子创建一个名为mytable的表格,包含五个字段,idnameemailphoneaddressid是一个序列主键,email是一个唯一值,phone是一个检查约束,要求必须是10位数字,address是一个可选字段。我们可以使用INSERT INTO语句来插入数据。

sql = """INSERT INTO mytable (name, email, phone, address) 
                 VALUES (%s, %s, %s, %s)"""
  
records = [
         ('John Doe', 'johndoe@gmail.com', '9876543210', 'New York'),
         ('Jane Smith', 'janesmith@yahoo.com', '8765432109', 'Los Angeles')
       ]

try:
    cursor.executemany(sql, records)
    connection.commit()
    count = cursor.rowcount
    print(f"{count} record inserted.")
    
except (Exception, psycopg2.DatabaseError) as error:
    print(error)
    
finally:
    # closing database connection.
    if connection:
        cursor.close()
        connection.close()
        print("PostgreSQL connection is closed")

这个例子向mytable表中插入两行数据,包括姓名John Doe和邮箱johndoe@gmail.com,姓名Jane Smith和邮箱janesmith@yahoo.com

如果想要更新数据,可以使用UPDATE语句。

sql = """UPDATE mytable 
         SET name = %s, email = %s, phone = %s, address = %s 
         WHERE id = %s"""
  
values = ('Jim Doe', 'jimdoe@hotmail.com', '1234567890', 'Chicago', 1)

try:
    cursor.execute(sql, values)
    connection.commit()
    print("Record updated successfully.")
    
except (Exception, psycopg2.DatabaseError) as error:
    print(error)
    
finally:
    # closing database connection.
    if connection:
        cursor.close()
        connection.close()
        print("PostgreSQL connection is closed")

这个例子更新mytable表中id1的记录的姓名为Jim Doe,邮箱为jimdoe@hotmail.com,手机号码为1234567890,地址为Chicago

如果想要删除数据,可以使用DELETE语句。

sql = """DELETE FROM mytable 
         WHERE id = %s"""
  
value = (1,)

try:
    cursor.execute(sql, value)
    connection.commit()
    print("Record deleted successfully.")
    
except (Exception, psycopg2.DatabaseError) as error:
    print(error)
    
finally:
    # closing database connection.
    if connection:
        cursor.close()
        connection.close()
        print("PostgreSQL connection is closed")

这个例子删除mytable表中id1的这一行数据。

以上都是PostgreSQL数据库的操作方式。

SQLite数据库的连接与操作

我们可以使用sqlite3模块连接SQLite数据库。以下是一个例子:

import sqlite3

try:
    con = sqlite3.connect('database.db')
    cur = con.cursor()

    # Create table
    cur.execute('''CREATE TABLE users
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                 name text NOT NULL,
                 email text NOT NULL UNIQUE,
                 phone integer NOT NULL);''')

    # Insert a row of data
    cur.execute("INSERT INTO users (name, email, phone) VALUES (?,?,?)", ('Alice', 'alice@example.com', '123456'))

    # Save (commit) the changes
    con.commit()

    # Select all rows from the table
    cur.execute("SELECT id, name, email, phone FROM users")
    rows = cur.fetchall()
    for row in rows:
        print(row)

    # Update a row of data
    cur.execute("UPDATE users SET email=? WHERE name=?", ('bob@example.com', 'Bob'))

    # Save (commit) the changes
    con.commit()

    # Select all rows from the table
    cur.execute("SELECT id, name, email, phone FROM users")
    rows = cur.fetchall()
    for row in rows:
        print(row)

    # Delete a row of data
    cur.execute("DELETE FROM users WHERE name=?", ('Alice',))

    # Save (commit) the changes
    con.commit()

    # Close communication with the database
    cur.close()

except sqlite3.Error as e:
    print(e)
finally:
    if con:
        con.close()
        print('Database connection closed.')

这个例子创建了一个名为users的表格,然后进行连接操作,然后执行数据库操作,最后关闭连接。

如果想要创建表格,可以使用以下代码:

cur.execute('''CREATE TABLE students
             (id INTEGER PRIMARY KEY AUTOINCREMENT,
             name text NOT NULL,
             grade text NOT NULL,
             gender text NOT NULL);''')

这个例子创建一个名为students的表格,包含四个字段,idnamegradegenderid是一个自增主键,其他字段都不能为空。我们可以使用INSERT INTO语句来插入数据。

sql = ''' INSERT INTO students(name, grade, gender)
          VALUES (?,?,?)'''
          
student = ['Tom', '9th', 'Male']

try:
   cur.execute(sql, student)
   con.commit()
   print('Student added successfully.')

except sqlite3.Error as e:
    print('Error adding student:', e)

finally:
    if con:
        con.close()
        print('Database connection closed.')

这个例子向students表中插入一行数据,包括姓名Tom,班级9th,性别Male

如果想要更新数据,可以使用UPDATE语句。

sql = ''' UPDATE students
          SET name =?, grade =?, gender =?
          WHERE id =?'''
          
new_info = ['Mary', '10th', 'Female', 1]

try:
    cur.execute(sql, new_info)
    con.commit()
    print('Student info updated successfully.')
    
except sqlite3.Error as e:
    print('Error updating student info:', e)

finally:
    if con:
        con.close()
        print('Database connection closed.')

这个例子更新students表中id1的记录的姓名为Mary,班级10th,性别Female

如果想要删除数据,可以使用DELETE语句。

sql = ''' DELETE FROM students
          WHERE id =?'''
          
del_id = (1,)

try:
    cur.execute(sql, del_id)
    con.commit()
    print('Student deleted successfully.')
    
except sqlite3.Error as e:
    print('Error deleting student:', e)

finally:
    if con:
        con.close()
        print('Database connection closed.')

这个例子删除students表中id1的这一行数据。

以上都是SQLite数据库的操作方式。

操作非关系数据库

MongoDB数据库的连接与操作

我们可以使用pymongo模块连接MongoDB数据库。以下是一个例子:

from pymongo import MongoClient

client = MongoClient('localhost', 27017)
db = client['testdb']
collection = db['customers']

customer = {'name': 'John Doe',
            'email': 'johndoe@example.com',
            'phone': '123456'}

x = collection.insert_one(customer).inserted_id

print(x) # Output: ObjectId('...')

query = {'name': 'John Doe'}
x = collection.find_one(query)

print(x) # Output: { '_id': ObjectId('...'), 'name': 'John Doe', 'email': 'johndoe@example.com', 'phone': '123456' }

updated_data = {"$set": {"email": "johndoe@gmail.com"}}
x = collection.update_one(query, updated_data)

print(x.modified_count) # Output: 1

x = collection.delete_many({"phone": "123456"})

print(x.deleted_count) # Output: 1

这个例子连接MongoDB,创建了一个名为customers的集合,然后进行数据库操作。注意,MongoDB的操作方法和关系数据库略有不同。

如果你用过关系数据库,那么你就会发现MongoDB的操作方式类似于关系数据库的操作方式。不过,无论关系数据库还是非关系数据库,还是什么数据库,最终目的还是为了完成某些任务。通过本文,读者应该对Python、关系数据库、非关系数据库、SQL、NoSQL和NewSQL有一个全面的了解。希望大家能对Python的数据库操作有所帮助。