1. Python数据库操作基础与核心概念
Python作为当今最流行的通用编程语言之一,其数据库操作能力是开发者必须掌握的核心技能。在实际项目中,我们经常需要与各种数据库系统交互,从简单的数据存储到复杂的分析处理都离不开数据库支持。
Python 3.8+版本对数据库操作进行了多项优化,特别是在异步IO和类型提示方面。通过标准库sqlite3或第三方库如SQLAlchemy、Psycopg2等,开发者可以轻松连接MySQL、PostgreSQL、Oracle等主流关系型数据库,也能操作MongoDB等NoSQL数据库。
提示:新手建议从SQLite开始学习,它无需安装服务端,单个文件即可作为完整数据库使用,非常适合练手和快速原型开发。
数据库基本操作遵循CRUD模式(Create创建、Read读取、Update更新、Delete删除),这是所有数据库交互的基础。Python通过统一的DB-API 2.0规范为不同数据库提供一致的操作接口,大大降低了学习成本。
2. 环境准备与数据库连接
2.1 Python环境配置
推荐使用Python 3.8或更高版本,这些版本对数据库操作有更好的支持。可以通过以下命令检查Python版本:
bash复制python --version
对于开发环境,VSCode配合Python插件是很好的选择。安装Python扩展后,可以方便地进行代码调试和数据库操作。Pycharm专业版也内置了强大的数据库工具,适合企业级开发。
2.2 数据库驱动安装
不同数据库需要安装对应的Python驱动:
bash复制# MySQL
pip install mysql-connector-python
# PostgreSQL
pip install psycopg2
# SQLite(Python内置,无需安装)
对于Oracle等商业数据库,需要下载官方驱动并配置环境变量。达梦数据库等国产数据库也提供了专门的Python接口。
2.3 建立数据库连接
以MySQL为例,连接数据库的标准方式:
python复制import mysql.connector
config = {
'user': 'username',
'password': 'password',
'host': '127.0.0.1',
'database': 'test_db',
'raise_on_warnings': True
}
try:
conn = mysql.connector.connect(**config)
print("数据库连接成功")
except mysql.connector.Error as err:
print(f"连接失败: {err}")
finally:
if 'conn' in locals() and conn.is_connected():
conn.close()
注意:生产环境中不要将密码硬编码在代码中,应该使用环境变量或配置中心管理敏感信息。
3. 数据库基本操作实战
3.1 创建表结构
在操作数据前,需要先定义表结构。SQLite示例:
python复制import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# 创建用户表
cursor.execute('''CREATE TABLE IF NOT EXISTS users
(id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER,
email TEXT UNIQUE)''')
conn.commit()
3.2 数据插入操作
单条插入:
python复制cursor.execute("INSERT INTO users (name, age, email) VALUES (?, ?, ?)",
('张三', 25, 'zhangsan@example.com'))
批量插入效率更高:
python复制users = [
('李四', 30, 'lisi@example.com'),
('王五', 28, 'wangwu@example.com')
]
cursor.executemany("INSERT INTO users (name, age, email) VALUES (?, ?, ?)", users)
conn.commit()
3.3 数据查询操作
基本查询:
python复制cursor.execute("SELECT * FROM users WHERE age > ?", (25,))
for row in cursor:
print(f"ID: {row[0]}, 姓名: {row[1]}, 年龄: {row[2]}")
使用字典形式返回结果更易读:
python复制conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
for row in cursor:
print(f"ID: {row['id']}, 邮箱: {row['email']}")
3.4 数据更新与删除
更新操作:
python复制cursor.execute("UPDATE users SET age = ? WHERE name = ?", (26, '张三'))
print(f"影响行数: {cursor.rowcount}")
conn.commit()
删除操作:
python复制cursor.execute("DELETE FROM users WHERE id = ?", (3,))
conn.commit()
4. 高级数据库操作技巧
4.1 事务处理
数据库事务是保证数据一致性的关键机制:
python复制try:
conn.start_transaction()
cursor.execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1")
cursor.execute("UPDATE accounts SET balance = balance + 100 WHERE id = 2")
conn.commit()
except Exception as e:
conn.rollback()
print(f"事务失败: {e}")
4.2 使用ORM框架
SQLAlchemy是Python最流行的ORM工具:
python复制from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
engine = create_engine('sqlite:///example.db')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
new_user = User(name='赵六', age=35)
session.add(new_user)
session.commit()
4.3 数据库连接池
高并发场景下应使用连接池:
python复制from mysql.connector import pooling
dbconfig = {
"host": "localhost",
"user": "root",
"password": "password",
"database": "test"
}
connection_pool = pooling.MySQLConnectionPool(
pool_name="mypool",
pool_size=5,
**dbconfig
)
conn = connection_pool.get_connection()
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
conn.close()
5. 常见问题与性能优化
5.1 连接超时问题
数据库连接默认有超时限制,长时间空闲后可能断开。解决方法:
python复制# 增加连接参数
config = {
'pool_name': 'mypool',
'pool_size': 5,
'pool_reset_session': True,
'connect_timeout': 30,
'connection_parameters': {
'wait_timeout': 28800
}
}
5.2 死锁处理
数据库死锁是常见问题,可以通过以下方式避免:
- 按固定顺序访问多张表
- 减小事务范围
- 设置合理的锁超时时间
python复制# MySQL设置锁超时为5秒
cursor.execute("SET innodb_lock_wait_timeout = 5")
5.3 批量操作优化
大量数据操作时,批量处理能显著提升性能:
python复制# 不好的做法
for item in data_list:
cursor.execute("INSERT INTO table VALUES (%s, %s)", (item[0], item[1]))
# 推荐做法
cursor.executemany("INSERT INTO table VALUES (%s, %s)", data_list)
conn.commit()
5.4 数据库备份与恢复
Python可以实现自动化备份:
python复制import subprocess
from datetime import datetime
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_file = f"backup_{timestamp}.sql"
# MySQL备份
subprocess.run(f"mysqldump -u root -p password dbname > {backup_file}", shell=True)
# SQLite备份
conn = sqlite3.connect('original.db')
backup = sqlite3.connect('backup.db')
conn.backup(backup)
6. 不同数据库的特殊处理
6.1 PostgreSQL特有功能
PostgreSQL支持JSON类型和高级地理空间数据:
python复制cursor.execute("""
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
attributes JSONB,
location GEOGRAPHY(POINT)
)
""")
cursor.execute("""
INSERT INTO products (name, attributes, location)
VALUES (%s, %s, ST_GeomFromText(%s))
""", ('商品1', '{"color": "red", "size": "L"}', 'POINT(116.404 39.915)'))
6.2 Oracle数据库注意事项
Oracle的CLOB/BLOB类型需要特殊处理:
python复制# 插入大文本
text_data = "很长的文本..." * 1000
cursor.setinputsizes(None, cx_Oracle.CLOB)
cursor.execute("INSERT INTO documents (id, content) VALUES (:1, :2)",
(1, text_data))
6.3 MongoDB等NoSQL操作
使用PyMongo操作MongoDB:
python复制from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
db = client['test_database']
collection = db['users']
# 插入文档
user = {
"name": "张三",
"age": 25,
"hobbies": ["篮球", "音乐"]
}
collection.insert_one(user)
# 查询
for doc in collection.find({"age": {"$gt": 20}}):
print(doc)
7. 数据库安全最佳实践
7.1 SQL注入防护
永远不要拼接SQL语句:
python复制# 危险做法
name = input("输入姓名: ")
cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")
# 安全做法
cursor.execute("SELECT * FROM users WHERE name = %s", (name,))
7.2 敏感数据加密
数据库中的密码等敏感信息应该加密存储:
python复制from hashlib import sha256
def hash_password(password):
return sha256(password.encode()).hexdigest()
password = "mypassword123"
hashed = hash_password(password)
cursor.execute("INSERT INTO users (username, password) VALUES (%s, %s)",
("user1", hashed))
7.3 权限最小化原则
数据库用户应该只有必要的权限:
sql复制-- 创建只读用户
CREATE USER 'reader'@'%' IDENTIFIED BY 'password';
GRANT SELECT ON database.* TO 'reader'@'%';
8. 数据库调试与性能分析
8.1 慢查询日志分析
MySQL开启慢查询日志:
python复制cursor.execute("SET GLOBAL slow_query_log = 'ON'")
cursor.execute("SET GLOBAL long_query_time = 1") # 超过1秒的查询
cursor.execute("SET GLOBAL slow_query_log_file = '/var/log/mysql/mysql-slow.log'")
8.2 使用EXPLAIN分析查询
查看SQL执行计划:
python复制cursor.execute("EXPLAIN SELECT * FROM users WHERE age > 20")
for row in cursor:
print(row)
8.3 Python性能分析工具
使用cProfile分析数据库操作性能:
python复制import cProfile
def query_users():
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE age > ?", (20,))
return cursor.fetchall()
cProfile.run('query_users()')
9. 数据库版本迁移与管理
9.1 使用Alembic进行迁移
SQLAlchemy的迁移工具:
bash复制pip install alembic
alembic init migrations
编辑alembic.ini配置数据库连接,然后创建迁移脚本:
bash复制alembic revision -m "create user table"
9.2 手动迁移策略
对于简单的迁移需求,可以编写Python脚本:
python复制def migrate_v1_to_v2(conn):
cursor = conn.cursor()
try:
cursor.execute("ALTER TABLE users ADD COLUMN phone TEXT")
conn.commit()
except sqlite3.OperationalError as e:
print(f"迁移失败: {e}")
conn.rollback()
9.3 数据库差异比较
使用sqlite_diff工具比较两个SQLite数据库:
python复制import sqlite3
def compare_dbs(db1, db2):
conn1 = sqlite3.connect(db1)
conn2 = sqlite3.connect(db2)
# 比较表结构
cursor1 = conn1.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables1 = set(row[0] for row in cursor1)
cursor2 = conn2.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables2 = set(row[0] for row in cursor2)
print(f"表差异: {tables1.symmetric_difference(tables2)}")
10. 实战项目:构建小型数据库应用
10.1 需求分析
开发一个简单的联系人管理系统,需要实现:
- 联系人增删改查
- 按姓名/电话搜索
- 数据导出/导入
- 用户权限管理
10.2 数据库设计
python复制def init_db():
conn = sqlite3.connect('contacts.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS contacts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
phone TEXT UNIQUE,
email TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
is_admin BOOLEAN DEFAULT 0
)
''')
conn.commit()
conn.close()
10.3 核心功能实现
添加联系人:
python复制def add_contact(name, phone, email=None):
conn = sqlite3.connect('contacts.db')
try:
conn.execute("INSERT INTO contacts (name, phone, email) VALUES (?, ?, ?)",
(name, phone, email))
conn.commit()
return True
except sqlite3.IntegrityError:
print("电话号码已存在")
return False
finally:
conn.close()
搜索联系人:
python复制def search_contacts(keyword):
conn = sqlite3.connect('contacts.db')
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute('''
SELECT * FROM contacts
WHERE name LIKE ? OR phone LIKE ? OR email LIKE ?
''', (f"%{keyword}%", f"%{keyword}%", f"%{keyword}%"))
results = [dict(row) for row in cursor]
conn.close()
return results
10.4 用户界面集成
使用Flask创建Web界面:
python复制from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/')
def index():
search = request.args.get('search', '')
contacts = search_contacts(search) if search else []
return render_template('index.html', contacts=contacts)
@app.route('/add', methods=['POST'])
def add():
name = request.form['name']
phone = request.form['phone']
email = request.form.get('email')
if add_contact(name, phone, email):
return "添加成功", 201
return "添加失败", 400
if __name__ == '__main__':
init_db()
app.run(debug=True)
11. 数据库操作中的Python高级特性应用
11.1 使用上下文管理器管理连接
自定义数据库连接的上下文管理器:
python复制from contextlib import contextmanager
@contextmanager
def db_connection(db_url):
conn = sqlite3.connect(db_url)
conn.row_factory = sqlite3.Row
try:
yield conn
except Exception as e:
conn.rollback()
raise e
finally:
conn.close()
# 使用示例
with db_connection('example.db') as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
for row in cursor:
print(row['name'])
11.2 使用生成器处理大量数据
避免内存溢出,使用生成器逐行处理:
python复制def iter_large_results(query, params=(), chunk_size=1000):
conn = sqlite3.connect('large.db')
cursor = conn.cursor()
cursor.execute(query, params)
while True:
rows = cursor.fetchmany(chunk_size)
if not rows:
break
for row in rows:
yield row
conn.close()
# 使用示例
for row in iter_large_results("SELECT * FROM huge_table"):
process_row(row)
11.3 异步数据库操作
使用aiomysql进行异步MySQL操作:
python复制import asyncio
import aiomysql
async def async_query():
conn = await aiomysql.connect(
host='localhost',
user='root',
password='password',
db='test'
)
async with conn.cursor() as cursor:
await cursor.execute("SELECT * FROM users")
result = await cursor.fetchall()
print(result)
conn.close()
asyncio.run(async_query())
12. 数据库测试与Mock
12.1 单元测试中的数据库测试
使用pytest测试数据库操作:
python复制import pytest
@pytest.fixture
def test_db():
conn = sqlite3.connect(':memory:')
conn.execute("CREATE TABLE test (id INTEGER, name TEXT)")
yield conn
conn.close()
def test_insert(test_db):
test_db.execute("INSERT INTO test VALUES (1, '测试')")
cursor = test_db.execute("SELECT * FROM test")
assert cursor.fetchone() == (1, '测试')
12.2 使用unittest.mock模拟数据库
测试时不依赖真实数据库:
python复制from unittest.mock import MagicMock
def test_user_query():
mock_conn = MagicMock()
mock_cursor = MagicMock()
mock_conn.cursor.return_value = mock_cursor
# 设置模拟返回值
mock_cursor.fetchall.return_value = [(1, '张三', 25)]
# 调用被测函数
result = get_users(mock_conn)
assert result == [{'id': 1, 'name': '张三', 'age': 25}]
mock_cursor.execute.assert_called_once_with("SELECT * FROM users")
12.3 数据库测试数据生成
使用Faker生成测试数据:
python复制from faker import Faker
def populate_test_data(num_records):
fake = Faker('zh_CN')
conn = sqlite3.connect('test.db')
for _ in range(num_records):
name = fake.name()
age = fake.random_int(18, 60)
email = fake.email()
conn.execute("INSERT INTO users (name, age, email) VALUES (?, ?, ?)",
(name, age, email))
conn.commit()
conn.close()
13. 数据库监控与维护
13.1 数据库健康检查
定期检查数据库状态:
python复制def check_db_health(conn):
cursor = conn.cursor()
# 检查表完整性
cursor.execute("PRAGMA integrity_check")
integrity = cursor.fetchone()
# 检查空间使用
cursor.execute("PRAGMA page_count")
page_count = cursor.fetchone()[0]
cursor.execute("PRAGMA page_size")
page_size = cursor.fetchone()[0]
total_size = page_count * page_size
return {
'integrity': integrity[0],
'total_size': f"{total_size/1024/1024:.2f}MB"
}
13.2 自动化维护任务
使用Python脚本执行定期维护:
python复制import schedule
import time
def vacuum_db():
conn = sqlite3.connect('app.db')
conn.execute("VACUUM")
conn.close()
def backup_db():
timestamp = time.strftime("%Y%m%d")
subprocess.run(f"sqlite3 app.db '.backup backup_{timestamp}.db'", shell=True)
# 每天凌晨3点执行
schedule.every().day.at("03:00").do(vacuum_db)
schedule.every().sunday.at("04:00").do(backup_db)
while True:
schedule.run_pending()
time.sleep(60)
13.3 性能监控仪表盘
使用Prometheus监控数据库指标:
python复制from prometheus_client import start_http_server, Gauge
import time
db_connections = Gauge('db_connections', 'Active database connections')
query_duration = Gauge('query_duration_seconds', 'Query execution time')
def monitor_db():
start_http_server(8000)
while True:
conn = sqlite3.connect('monitor.db')
start_time = time.time()
conn.execute("SELECT 1")
query_duration.set(time.time() - start_time)
cursor = conn.execute("PRAGMA database_list")
db_connections.set(len(cursor.fetchall()))
conn.close()
time.sleep(15)
14. 数据库与Python生态集成
14.1 与Pandas的数据交互
将查询结果转为DataFrame:
python复制import pandas as pd
def query_to_dataframe(query, params=()):
conn = sqlite3.connect('data.db')
df = pd.read_sql(query, conn, params=params)
conn.close()
return df
# 使用示例
df = query_to_dataframe("SELECT * FROM sales WHERE date > ?", ('2023-01-01',))
print(df.describe())
14.2 使用Django ORM
Django内置强大的ORM系统:
python复制from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
created_at = models.DateTimeField(auto_now_add=True)
# 查询示例
users = User.objects.filter(age__gt=20).order_by('-created_at')
for user in users:
print(user.name, user.age)
14.3 数据库与机器学习
使用数据库数据训练模型:
python复制from sklearn.ensemble import RandomForestClassifier
import pandas as pd
# 从数据库加载数据
conn = sqlite3.connect('ml_data.db')
df = pd.read_sql("SELECT * FROM training_data", conn)
conn.close()
# 准备特征和标签
X = df.drop('target', axis=1)
y = df['target']
# 训练模型
model = RandomForestClassifier()
model.fit(X, y)
# 保存模型到数据库
import pickle
model_blob = pickle.dumps(model)
conn = sqlite3.connect('models.db')
conn.execute("INSERT INTO models (name, data) VALUES (?, ?)",
("random_forest", model_blob))
conn.commit()
conn.close()
15. 数据库安全审计与合规
15.1 操作日志记录
记录所有数据库操作:
python复制def audit_log(action, table, user, details):
conn = sqlite3.connect('audit.db')
cursor = conn.cursor()
cursor.execute('''
INSERT INTO audit_log
(action, table_name, user_id, details, timestamp)
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
''', (action, table, user, str(details)))
conn.commit()
conn.close()
# 包装数据库操作用于审计
def execute_with_audit(cursor, query, params, user):
try:
cursor.execute(query, params)
audit_log('EXECUTE', query.split()[1], user, {'query': query, 'params': params})
except Exception as e:
audit_log('ERROR', query.split()[1], user, {'error': str(e)})
raise
15.2 数据脱敏处理
敏感数据查询时脱敏:
python复制def get_user_info(user_id):
conn = sqlite3.connect('users.db')
cursor = conn.cursor()
cursor.execute("SELECT id, name, phone, email FROM users WHERE id = ?", (user_id,))
user = cursor.fetchone()
conn.close()
if user:
return {
'id': user[0],
'name': user[1],
'phone': user[2][:3] + '****' + user[2][-4:],
'email': user[3].split('@')[0][:2] + '***@' + user[3].split('@')[1]
}
return None
15.3 数据库权限管理
实现行级权限控制:
python复制def get_visible_records(user_role):
conn = sqlite3.connect('data.db')
cursor = conn.cursor()
if user_role == 'admin':
cursor.execute("SELECT * FROM sensitive_data")
elif user_role == 'manager':
cursor.execute("SELECT id, name FROM sensitive_data WHERE department = ?",
(user_department,))
else:
cursor.execute("SELECT id FROM sensitive_data WHERE owner = ?",
(user_id,))
return cursor.fetchall()
16. 数据库架构设计与优化
16.1 数据库分表策略
按时间范围分表:
python复制def get_user_table(year):
return f"users_{year}"
def query_users_by_year(year, name):
table = get_user_table(year)
conn = sqlite3.connect('partitioned.db')
cursor = conn.cursor()
try:
cursor.execute(f"SELECT * FROM {table} WHERE name LIKE ?", (f"%{name}%",))
return cursor.fetchall()
finally:
conn.close()
16.2 读写分离实现
基本读写分离路由:
python复制class DBRouter:
def __init__(self):
self.read_conn = sqlite3.connect('read_replica.db')
self.write_conn = sqlite3.connect('primary.db')
def get_connection(self, read_only=False):
return self.read_conn if read_only else self.write_conn
router = DBRouter()
# 读操作
read_conn = router.get_connection(read_only=True)
cursor = read_conn.cursor()
cursor.execute("SELECT * FROM products")
# 写操作
write_conn = router.get_connection()
cursor = write_conn.cursor()
cursor.execute("INSERT INTO products VALUES (...)")
write_conn.commit()
16.3 缓存策略优化
使用Redis缓存查询结果:
python复制import redis
import pickle
r = redis.Redis(host='localhost', port=6379)
def cached_query(query, params=(), ttl=300):
cache_key = f"query:{hash((query, params))}"
# 尝试从缓存获取
cached = r.get(cache_key)
if cached:
return pickle.loads(cached)
# 执行数据库查询
conn = sqlite3.connect('app.db')
cursor = conn.cursor()
cursor.execute(query, params)
result = cursor.fetchall()
conn.close()
# 存入缓存
r.setex(cache_key, ttl, pickle.dumps(result))
return result
17. 数据库与微服务架构
17.1 多数据库服务集成
不同微服务使用独立数据库:
python复制# 用户服务
user_conn = sqlite3.connect('user_service.db')
# 订单服务
order_conn = sqlite3.connect('order_service.db')
# 跨服务查询需要API调用
def get_user_orders(user_id):
user = user_conn.execute("SELECT * FROM users WHERE id = ?", (user_id,)).fetchone()
if not user:
return None
# 实际项目中这里应该是HTTP请求
orders = order_conn.execute(
"SELECT * FROM orders WHERE user_id = ?", (user_id,)
).fetchall()
return {
'user': user,
'orders': orders
}
17.2 事件溯源模式
实现事件存储:
python复制def record_event(event_type, aggregate_id, data):
conn = sqlite3.connect('event_store.db')
cursor = conn.cursor()
cursor.execute('''
INSERT INTO events
(event_type, aggregate_id, data, timestamp)
VALUES (?, ?, ?, CURRENT_TIMESTAMP)
''', (event_type, aggregate_id, json.dumps(data)))
conn.commit()
conn.close()
def replay_events(aggregate_id):
conn = sqlite3.connect('event_store.db')
cursor = conn.cursor()
cursor.execute('''
SELECT event_type, data FROM events
WHERE aggregate_id = ?
ORDER BY timestamp
''', (aggregate_id,))
return [(row[0], json.loads(row[1])) for row in cursor]
17.3 分布式事务处理
Saga模式实现:
python复制def create_order_saga(user_id, product_id, quantity):
try:
# 第一步:预留库存
inventory_conn = sqlite3.connect('inventory.db')
inventory_conn.execute(
"UPDATE products SET reserved = reserved + ? WHERE id = ? AND stock >= reserved + ?",
(quantity, product_id, quantity)
)
inventory_conn.commit()
# 第二步:创建订单
order_conn = sqlite3.connect('orders.db')
order_conn.execute(
"INSERT INTO orders (user_id, product_id, quantity) VALUES (?, ?, ?)",
(user_id, product_id, quantity)
)
order_conn.commit()
# 第三步:扣减库存
inventory_conn.execute(
"UPDATE products SET stock = stock - ?, reserved = reserved - ? WHERE id = ?",
(quantity, quantity, product_id)
)
inventory_conn.commit()
return True
except Exception as e:
# 补偿操作
inventory_conn.rollback()
order_conn.rollback()
print(f"订单创建失败: {e}")
return False
finally:
inventory_conn.close()
order_conn.close()
18. 数据库新技术探索
18.1 向量数据库应用
使用Pinecone进行向量搜索:
python复制import pinecone
import numpy as np
pinecone.init(api_key="your-api-key", environment="us-west1-gcp")
index = pinecone.Index("product-vectors")
# 存储向量
vectors = [
("vec1", np.random.rand(100).tolist(), {"product_id": "123"}),
("vec2", np.random.rand(100).tolist(), {"product_id": "456"})
]
index.upsert(vectors=vectors)
# 向量搜索
query_vec = np.random.rand(100).tolist()
results = index.query(queries=[query_vec], top_k=2)
print(results)
18.2 图数据库操作
使用Neo4j进行图数据查询:
python复制from neo4j import GraphDatabase
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password"))
def query_friends_of_friends(name):
with driver.session() as session:
result = session.run("""
MATCH (p:Person {name: $name})-[:FRIEND]->(friend)-[:FRIEND]->(fof)
RETURN fof.name AS name
""", name=name)
return [record["name"] for record in result]
print(query_friends_of_friends("Alice"))
18.3 时序数据库应用
使用InfluxDB记录时间序列数据:
python复制from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS
client = InfluxDBClient(url="http://localhost:8086", token="my-token", org="my-org")
write_api = client.write_api(write_options=SYNCHRONOUS)
point = Point("temperature")\
.tag("location", "server-room")\
.field("value", 25.3)\
.time(datetime.utcnow())
write_api.write(bucket="my-bucket", record=point)
19. 数据库文档与知识管理
19.1 自动生成数据库文档
使用Python提取数据库元数据:
python复制def generate_db_docs(db_path, output_file):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
with open(output_file, 'w') as f:
# 获取所有表
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables = cursor.fetchall()
for table in tables:
table_name = table[0]
f.write(f"## 表: {table_name}\n\n")
# 获取表结构
cursor.execute(f"PRAGMA table_info({table_name})")
columns = cursor.fetchall()
f.write("| 列名 | 类型 | 是否为空 | 默认值 | 主键 |\n")
f.write("|------|------|---------|-------|-----|\n")
for col in columns:
f.write(f"| {col[1]} | {col[2]} | {'否' if col[3] else '是'} | {col[4] or ''} | {'是' if col[5] else '否'} |\n")
f.write("\n")
conn.close()
19.2 数据库变更管理
记录数据库变更历史:
python复制def record_migration(version, description, script):
conn = sqlite3.connect('migrations.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS migrations (
version TEXT PRIMARY KEY,
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
description TEXT,
script TEXT
)
''')
cursor.execute('''
INSERT INTO migrations (version, description, script)
VALUES (?, ?, ?)
''', (version, description, script))
conn.commit()
conn.close()
19.3 数据库知识图谱构建
从数据库关系构建知识图谱:
python复制def build_kg(db_path):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# 获取所有外键关系
cursor.execute("PRAGMA foreign_key_list")
relations = cursor.fetchall()
kg = {
"nodes": [],
"links": []
}
# 添加表作为节点
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
for table in cursor.fetchall():
kg["nodes"].append({
"id": table[0],
"label": table[0],
"type": "table"
})
# 添加外键关系作为边
for rel in relations:
kg["links"].append({
"source": rel[2], # from表
"target": rel[3], # to表
"type": "foreign_key",
"relation": f"{rel[2]}.{rel[4]} → {rel[3]}.{rel[5]}"
})
conn.close()
return kg
20. 数据库职业发展与学习路径
20.1 数据库相关职业方向
-
数据库管理员(DBA):
- 负责数据库安装、配置、备份恢复
- 性能调优和容量规划
- 需要熟悉SQL和特定数据库系统
-
数据工程师:
- 构建和维护数据管道
