杰瑞科技汇

python database api

Of course! The Python Database API (often referred to as DB-API 2.0) is a standard specification for connecting to and interacting with relational databases from Python. It's not a concrete library but a set of guidelines that database driver authors follow.

python database api-图1
(图片来源网络,侵删)

This standardization is incredibly powerful because it allows you to write database-agnostic code. If you learn the DB-API, you can switch from SQLite to PostgreSQL to MySQL with minimal changes to your application logic, as long as you use a driver that complies with the standard.

Let's break it down.

The Core Idea: A Common Interface

Imagine you have different types of cars (Toyota, Ford, BMW). They all have a steering wheel, an accelerator, and brakes. You don't need to learn a completely new way to drive each one. The DB-API is like the standard "driving interface" for databases.

The key components of this interface are:

python database api-图2
(图片来源网络,侵删)
  1. Connection Objects: Manage the connection to a specific database.
  2. Cursor Objects: Allow you to execute SQL commands and fetch results.
  3. Exceptions: Provide a standard way to handle errors.

The DB-API Workflow (The "Pythonic Way")

Here is the standard, recommended pattern for interacting with a database using the DB-API. It's robust because it ensures resources are always closed, even if errors occur.

import sqlite3  # We'll use SQLite as it's built-in and perfect for examples
# 1. Establish a connection
#    The connection string varies by database driver.
#    For SQLite, it's just the database file name.
try:
    conn = sqlite3.connect('my_database.db')
    # 2. Create a cursor object
    #    The cursor is your primary tool for executing commands.
    cursor = conn.cursor()
    # 3. Execute a SQL command
    #    Use '?' as a placeholder for parameters. This is CRUCIAL for security (prevents SQL injection).
    cursor.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)")
    # 4. For commands that modify data (INSERT, UPDATE, DELETE), commit the transaction
    #    This saves the changes to the database.
    conn.commit()
    print("Table 'users' created successfully.")
    # 5. Execute a query to fetch data
    cursor.execute("SELECT * FROM users")
    #    fetchone() gets the next row of a query result set.
    #    fetchall() retrieves all remaining rows.
    #    fetchmany(size) retrieves a specific number of rows.
    rows = cursor.fetchall()
    print("Current users in the database:")
    for row in rows:
        print(row)
except sqlite3.Error as e:
    # 6. Handle potential database errors
    print(f"Database error: {e}")
finally:
    # 7. Always close the cursor and connection
    #    This is the most important step for releasing resources.
    if 'cursor' in locals():
        cursor.close()
    if 'conn' in locals():
        conn.close()
    print("Database connection closed.")

Key DB-API Components Explained

Connection Objects

You get a connection object from the driver's connect() function.

  • connect(...): The main function to establish a connection. It takes parameters specific to the database (host, user, password, database name, etc.).
  • .cursor(): Returns a new Cursor object.
  • .commit(): Commits the current transaction. Without this, any INSERT, UPDATE, or DELETE commands will not be saved.
  • .rollback(): Rolls back the current transaction to the last commit.
  • .close(): Closes the connection and releases any associated resources.

Cursor Objects

The cursor is your workhorse for executing commands.

  • .execute(sql [, parameters]): Executes a single SQL command. You must use parameter substitution (e.g., for SQLite, %s for psycopg2) to prevent SQL injection.
  • .executemany(sql, seq_of_parameters): Executes a command for each sequence of parameters in the provided list. Useful for bulk inserts.
  • .fetchone(): Fetches the next row of a query result set. Returns a tuple or None.
  • .fetchall(): Fetches all remaining rows of a query result set. Returns a list of tuples.
  • .fetchmany([size]): Fetches the next set of rows of a query result. Returns a list of tuples.
  • .rowcount: Read-only attribute that returns the number of rows affected by the last execute() or executemany() call (for DML statements like INSERT, UPDATE, DELETE).
  • .close(): Closes the cursor.

Exceptions

The DB-API defines a set of standard exception classes that are hierarchical. This allows you to catch specific errors or general ones.

python database api-图3
(图片来源网络,侵删)
  • Error: The base class for all exceptions.
    • Warning: A non-fatal warning.
    • InterfaceError: Errors related to the database interface, not the database itself.
    • DatabaseError: Errors related to the database.
      • DataError: Errors due to problems with the data (e.g., division by zero, value out of range).
      • OperationalError: Errors related to the database's operation (e.g., connection lost, table not found). These are often not "programming" errors.
      • IntegrityError: Violation of a relational integrity constraint (e.g., foreign key, unique constraint).
      • InternalError: The database encountered an internal error (e.g., cursor is invalid).
      • ProgrammingError: Errors due to the Python program (e.g., table not found, SQL syntax error).
      • NotSupportedError: A method or database API is not supported by the database.

Choosing a Driver: Examples for Popular Databases

You need to install a specific driver for each database you want to use. Here are some of the most popular ones.

Database Python Driver Installation Command
SQLite sqlite3 Built-in (No installation needed)
PostgreSQL psycopg2 pip install psycopg2-binary
MySQL / MariaDB mysql-connector-python pip install mysql-connector-python
MySQL / MariaDB PyMySQL pip install PyMySQL
SQL Server pyodbc pip install pyodbc
Oracle cx_Oracle pip install cx_Oracle

Example: PostgreSQL with psycopg2

The workflow is identical, just with a different connection string.

import psycopg2 # Make sure you've installed it: pip install psycopg2-binary
# Connection parameters are different for PostgreSQL
conn_params = {
    "host": "localhost",
    "database": "mydb",
    "user": "myuser",
    "password": "mypassword"
}
try:
    # 1. Establish a connection
    conn = psycopg2.connect(**conn_params)
    cursor = conn.cursor()
    # 2. Execute a command
    # Note: psycopg2 uses %s for placeholders, not ?
    cursor.execute("INSERT INTO users (name, email) VALUES (%s, %s)", ('Alice', 'alice@example.com'))
    conn.commit() # Commit the transaction
    # 3. Fetch data
    cursor.execute("SELECT * FROM users WHERE name = %s", ('Alice',))
    user = cursor.fetchone() # Fetch one row
    print(f"Found user: {user}")
except psycopg2.Error as e:
    print(f"PostgreSQL error: {e}")
finally:
    if 'cursor' in locals():
        cursor.close()
    if 'conn' in locals():
        conn.close()

Modern Alternatives to Raw DB-API

While the DB-API is the foundation, writing raw SQL and managing connections manually can be tedious. This has led to the rise of several powerful libraries that build on top of the DB-API.

SQLAlchemy

SQLAlchemy is the de-facto standard for database interaction in Python. It's an "Object Relational Mapper" (ORM) that allows you to interact with your database using Python objects instead of writing raw SQL.

  • Pros: Database-agnostic code, powerful ORM, connection pooling, transaction management.
  • Cons: Steeper learning curve, can be slower for very complex queries.

Example (SQLAlchemy ORM):

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# 1. Setup
Base = declarative_base()
engine = create_engine('sqlite:///my_database.db') # Still uses a DB-API driver underneath!
Session = sessionmaker(bind=engine)
session = Session()
# 2. Define a mapped class (Python object that maps to a table)
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    email = Column(String)
# 3. Interact with the database using Python objects
new_user = User(name='Bob', email='bob@example.com')
session.add(new_user)
session.commit() # Commits the transaction
# 4. Query
users = session.query(User).all()
for user in users:
    print(f"User: {user.name}, Email: {user.email}")
session.close()

Django ORM

If you are using the Django web framework, it comes with its own powerful ORM that is tightly integrated with the framework. It abstracts away the database layer completely.

Peewee

A lightweight and simple ORM that is easier to learn than SQLAlchemy but still provides a lot of convenience.

Summary: When to Use What?

Method Best For Pros Cons
Raw DB-API Simple scripts, learning the fundamentals, maximum performance, no ORM overhead. - Standardized
- No extra dependencies (for SQLite)
- Full control over SQL
- Verbose code
- Manual connection/transaction management
- Prone to errors if not careful
SQLAlchemy Most applications, complex data models, need for database portability. - Powerful ORM and Core
- Excellent connection pooling
- High-level transaction control
- Steep learning curve
- Can be overkill for very simple tasks
Django ORM Projects built with the Django framework. - Seamless integration with Django
- Rapid development
- Secure by default
- Tied to the Django ecosystem
Peewee Small to medium-sized projects, developers who want a simpler ORM. - Lightweight and easy to learn
- Good documentation
- Less boilerplate than SQLAlchemy
- Less powerful and feature-rich than SQLAlchemy
分享:
扫描分享到社交APP
上一篇
下一篇