杰瑞科技汇

python peewee Mate

Of course! Let's dive into Peewee. I'll be your "Python Peewee Mate," guiding you through everything from the basics to more advanced topics.

python peewee Mate-图1
(图片来源网络,侵删)

What is Peewee?

Peewee is a simple, small, and fast ORM (Object-Relational Mapper) for Python. It's designed to be lightweight and intuitive, making it a fantastic choice for small to medium-sized projects, scripts, or anyone who wants to get a database up and running quickly without the complexity of a larger ORM like SQLAlchemy.

Key Features:

  • Simple & Lightweight: Easy to learn and use.
  • Supports Multiple Databases: Works out-of-the-box with SQLite, PostgreSQL, and MySQL.
  • Pythonic: You interact with your database using Python classes and objects, not raw SQL strings.
  • Built-in Features: Includes support for migrations, model validation, and a thread-safe connection pool.

The Core Concepts: The "Peewee Trinity"

To use Peewee, you need to understand three main things:

  1. The Database Connection: Represents your database.
  2. The Model: A Python class that maps to a database table.
  3. The Field: Defines the columns in your table (e.g., CharField, IntegerField).

Step 1: Installation

First, install Peewee. We'll also install psycopg2-binary for our PostgreSQL example.

python peewee Mate-图2
(图片来源网络,侵删)
pip install peewee
pip install psycopg2-binary  # For PostgreSQL

Step 2: Setting Up the Database and Models

Let's create a simple example for a blog application with Post and Category models.

Database Connection

Peewee makes it easy to connect to different databases. Here's how you'd set up connections for SQLite and PostgreSQL.

# For SQLite (great for development and small apps)
# This will create a 'my_database.db' file in your project directory.
db = SqliteDatabase('my_database.db')
# For PostgreSQL (and MySQL)
# from playhouse.postgres_ext import PostgresqlExtDatabase
#
# db = PostgresqlExtDatabase(
#     'my_app_db',  # Your database name
#     user='postgres', # Your username
#     password='mysecretpassword', # Your password
#     host='localhost', # Your host
#     port=5432 # Your port
# )

Defining Models

Now, let's define our models. A model is a simple Python class that inherits from peewee.Model.

  • db_class: We tell the model which database connection to use.
  • peewee.CharField: For text. max_length is required.
  • peewee.TextField: For longer text, like a blog post content.
  • peewee.DateTimeField: For storing dates and times. formats lets you control how it's displayed.
  • peewee.ForeignKeyField: For creating relationships between tables. This automatically creates a category_id column in the post table.
from peewee import *
from datetime import datetime
# Use the database connection we defined above
db = SqliteDatabase('my_database.db')
# Base model class that all our models will inherit from
class BaseModel(Model):
    class Meta:
        database = db # This model uses the 'db' database connection
class Category(BaseModel):
    name = CharField(unique=True) # e.g., "Technology", "Lifestyle"
class Post(BaseModel):= CharField()
    content = TextField()
    created_date = DateTimeField(default=datetime.now)
    # This creates a relationship to the Category model
    # backref='posts' lets you do `category.posts` to get all posts in that category
    category = ForeignKeyField(Category, backref='posts', null=True)
# --- This is crucial ---
# You must create the tables in the database.
# Peewee will not do this automatically.
# If the tables already exist, this is a safe operation.
db.connect()
db.create_tables([Category, Post])
db.close()

Step 3: The CRUD Operations (Create, Read, Update, Delete)

This is where the magic happens. We'll interact with our database using our Python objects.

python peewee Mate-图3
(图片来源网络,侵删)

C - Create

Let's add some categories and posts to our database.

# Make sure we're connected
db.connect()
# --- Creating a Category ---
# Method 1: Create and save in one step
tech_category = Category.create(name='Technology')
print(f"Created category: {tech_category.name} (ID: {tech_category.id})")
# Method 2: Create an instance and then save it
lifestyle_category = Category(name='Lifestyle')
lifestyle_category.save()
print(f"Saved category: {lifestyle_category.name} (ID: {lifestyle_category.id})")
# --- Creating a Post ---
# We can pass the category object directly!
post1 = Post.create('My First Peewee Post',
    content='Peewee is awesome and easy to use.',
    category=tech_category
)
print(f"Created post: '{post1.title}' in category '{post1.category.name}'")
# You can also use the ID
post2 = Post.create('Living a Healthy Life',
    content='Eat well and exercise regularly.',
    category=lifestyle_category
)
print(f"Created post: '{post2.title}' in category '{lifestyle_category.name}'")
db.close()

R - Read (Querying)

Peewee's querying syntax is very expressive.

db.connect()
# Get all categories
all_categories = Category.select()
print("\n--- All Categories ---")
for category in all_categories:
    print(f"- {category.name}")
# Get all posts
all_posts = Post.select()
print("\n--- All Posts ---")
for post in all_posts:
    print(f"- {post.title} (Category: {post.category.name})")
# Get a specific post by its ID
try:
    specific_post = Post.get_by_id(post1.id)
    print(f"\n--- Post with ID {post1.id} ---")
    print(f"Title: {specific_post.title}")
    print(f"Content: {specific_post.content}")
except Post.DoesNotExist:
    print(f"Post with ID {post1.id} not found.")
# Get posts in a specific category
tech_posts = Post.select().where(Post.category == tech_category)
print(f"\n--- Posts in '{tech_category.name}' category ---")
for post in tech_posts:
    print(f"- {post.title}")
# Get posts containing a specific word in the title
peewee_posts = Post.select().where(Post.title.contains('Peewee'))
print(f"\n--- Posts with 'Peewee' in the title ---")
for post in peewee_posts:
    print(f"- {post.title}")
# Ordering posts by creation date (newest first)
recent_posts = Post.select().order_by(Post.created_date.desc())
print(f"\n--- All Posts (Newest First) ---")
for post in recent_posts:
    print(f"- {post.title} on {post.created_date.strftime('%Y-%m-%d')}")
db.close()

U - Update

Updating is a two-step process: get the object, then change its attributes and save.

db.connect()
# Get the first post we created
post_to_update = Post.get_by_id(post1.id)
print(f"\nOriginal title: {post_to_update.title}")
# Update its title
post_to_update.title = "My Awesome Updated Peewee Post"
post_to_update.save() # This executes an UPDATE statement
# Verify the update
updated_post = Post.get_by_id(post1.id)
print(f"New title: {updated_post.title}")
db.close()

D - Delete

Deleting is also straightforward: get the object and call .delete().

db.connect()
# Get the post we want to delete
post_to_delete = Post.get_by_id(post2.id)
print(f"\nDeleting post: '{post_to_delete.title}'...")
# Delete the object
post_to_delete.delete()
# Verify it's gone
try:
    Post.get_by_id(post2.id)
    print("Post still exists!") # This line should not run
except Post.DoesNotExist:
    print("Post successfully deleted!")
db.close()

Advanced Topics

Transactions

Ensuring a group of operations all succeed or all fail is crucial. Peewee handles this with db.atomic().

db.connect()
try:
    with db.atomic(): # All code inside this block is part of a single transaction
        # Create a new category and a post for it
        new_cat = Category.create(name='Finance')
        Post.create(title='Budgeting 101', content='...', category=new_cat)
        print("Transaction successful!")
except Exception as e:
    print(f"Transaction failed! Rolled back. Error: {e}")
finally:
    db.close()

Migrations

As your application evolves, so will your database schema. Peewee has a built-in migration system.

  1. Install the helper:

    pip install playhouse.migrate
  2. Create a migration file: You can write a script to apply changes.

    from playhouse.migrate import *
    db.connect()
    # Let's add a new 'author' field to our Post model
    migrator = PostgresqlMigrator(db) # Use SqliteMigrator for SQLite
    # Add a new column
    migrate(
        migrator.add_column('post', 'author', CharField(default='Anonymous'))
    )
    # To rename a column: migrate(migrator.rename_column('post', 'content', 'body'))
    # To drop a column: migrate(migrator.drop_column('post', 'author'))
    db.close()
    print("Migration applied successfully!")

Summary: Why Peewee is a Great "Mate"

  • Low Barrier to Entry: You can be productive in minutes.
  • No Magic: It's very clear what SQL is being generated, which helps with learning and debugging.
  • Powerful Enough: For most applications, Peewee has all the features you need (complex queries, joins, aggregations, etc.).
  • Great for Scripts: Perfect for writing a quick Python script that needs to interact with a database.

Now you're equipped to be a confident Peewee user! Go build something amazing.

分享:
扫描分享到社交APP
上一篇
下一篇