Skip to content
Back to skills

1519 Queries 242163c5

ASecurity

**Problem**: Legacy API, deprecated in SQLAlchemy 2.0.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
businesspythongosqlapiperformance

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 1519-queries_242163c5 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1519 Queries 242163c5?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1519 Queries 242163c5
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1519-queries-242163c5/badge)](https://www.skillsdirectory.com/skills/tools-only-1519-queries-242163c5)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Queries

## Critical Anti-Patterns

### 1. Using Legacy query() Instead of select()

**Problem**: Legacy API, deprecated in SQLAlchemy 2.0.

```python
# BAD - legacy query() API (deprecated)
def get_active_users():
    with Session() as session:
        users = session.query(User).filter(User.active == True).all()
        return users

# GOOD - SQLAlchemy 2.0 select() syntax
from sqlalchemy import select

def get_active_users():
    with Session() as session:
        result = session.execute(
            select(User).where(User.active == True)
        )
        return result.scalars().all()

# ASYNC version
async def get_active_users():
    async with AsyncSession() as session:
        result = await session.execute(
            select(User).where(User.active == True)
        )
        return result.scalars().all()
```

### 2. Loading Full Objects When Only Columns Needed

**Problem**: ORM overhead, unnecessary data transfer.

```python
# BAD - loading full ORM objects just for one column
def get_user_emails():
    with Session() as session:
        users = session.execute(select(User)).scalars().all()
        return [user.email for user in users]  # Loaded entire object!

# GOOD - select only needed columns
def get_user_emails():
    with Session() as session:
        result = session.execute(
            select(User.email)
        )
        return result.scalars().all()

# BETTER - multiple columns as tuples
def get_user_info():
    with Session() as session:
        result = session.execute(
            select(User.id, User.name, User.email)
        )
        return result.all()  # Returns list of tuples
```

### 3. Using all() When Only One Result Expected

**Problem**: Confusing API, loads unnecessary data.

```python
# BAD - using all() when expecting one result
def get_user_by_email(email: str):
    with Session() as session:
        users = session.execute(
            select(User).where(User.email == email)
        ).scalars().all()
        return users[0] if users else None  # Awkward!

# GOOD - use scalar_one_or_none()
def get_user_by_email(email: str) -> User | None:
    with Session() as session:
        return session.execute(
            select(User).where(User.email == email)
        ).scalar_one_or_none()

# Use scalar_one() if must exist (raises if not found)
def get_user_by_id(user_id: int) -> User:
    with Session() as session:
        return session.execute(
            select(User).where(User.id == user_id)
        ).scalar_one()  # Raises NoResultFound or MultipleResultsFound
```

### 4. Not Using Bulk Operations

**Problem**: ORM overhead per object, slow inserts/updates.

```python
# BAD - ORM insert in loop
def create_users(user_data: list[dict]):
    with Session() as session:
        for data in user_data:
            user = User(**data)
            session.add(user)  # Individual ORM overhead per user
        session.commit()

# GOOD - bulk insert
def create_users(user_data: list[dict]):
    with Session() as session:
        session.bulk_insert_mappings(User, user_data)
        session.commit()

# BETTER - Core insert for maximum performance
from sqlalchemy import insert

def create_users(user_data: list[dict]):
    with Session() as session:
        session.execute(
            insert(User),
            user_data
        )
        session.commit()

# ASYNC bulk insert
async def create_users(user_data: list[dict]):
    async with AsyncSession() as session:
        await session.execute(
            insert(User),
            user_data
        )
        await session.commit()
```

### 5. Not Using Bulk Updates

**Problem**: ORM overhead, multiple UPDATE statements.

```python
# BAD - update in loop
def deactivate_old_users(cutoff_date):
    with Session() as session:
        users = session.execute(
            select(User).where(User.last_login < cutoff_date)
        ).scalars().all()

        for user in users:
            user.active = False  # Individual UPDATE per user
        session.commit()

# GOOD - single UPDATE statement
from sqlalchemy import update

def deactivate_old_users(cutoff_date):
    with Session() as session:
        session.execute(
            update(User)
            .where(User.last_login < cutoff_date)
            .values(active=False)
        )
        session.commit()

# ASYNC version
async def deactivate_old_users(cutoff_date):
    async with AsyncSession() as session:
        await session.execute(
            update(User)
            .where(User.last_login < cutoff_date)
            .values(active=False)
        )
        await session.commit()
```

### 6. Not Using exists() for Existence Checks

**Problem**: Loads unnecessary data just to check existence.

```python
# BAD - loading data just to check existence
def user_exists(email: str) -> bool:
    with Session() as session:
        user = session.execute(
            select(User).where(User.email == email)
        ).scalar_one_or_none()
        return user is not None  # Loaded entire object!

# GOOD - use exists()
from sqlalchemy import exists, select

def user_exists(email: str) -> bool:
    with Session() as session:
        return session.execute(
            select(exists().where(User.email == email))
        ).scalar()

# Alternative with count (less efficient but sometimes clearer)
from sqlalchemy import func

def user_exists(email: str) -> bool:
    with Session() as session:
        count = session.execute(
            select(func.count()).select_from(User).where(User.email == email)
        ).scalar()
        return count > 0
```

### 7. Not Using Pagination

**Problem**: Memory exhaustion on large result sets.

```python
# BAD - loading all results into memory
def get_all_users():
    with Session() as session:
        users = session.execute(select(User)).scalars().all()  # OOM on millions!
        return users

# GOOD - use limit/offset for pagination
def get_users_page(page: int = 1, page_size: int = 100):
    with Session() as session:
        offset = (page - 1) * page_size
        users = session.execute(
            select(User)
            .offset(offset)
            .limit(page_size)
        ).scalars().all()
        return users

# BETTER - use keyset pagination for large datasets
def get_users_after(last_id: int | None = None, page_size: int = 100):
    with Session() as session:
        query = select(User).order_by(User.id)
        if last_id:
            query = query.where(User.id > last_id)

        users = session.execute(
            query.limit(page_size)
        ).scalars().all()
        return users

# BEST - stream results for very large datasets
def stream_all_users():
    with Session() as session:
        result = session.execute(select(User))
        for user in result.scalars():  # Streams, doesn't load all
            yield user
```

### 8. Not Using with_for_update for Row Locking

**Problem**: Race conditions in concurrent updates.

```python
# BAD - race condition in concurrent requests
def decrement_stock(product_id: int, quantity: int):
    with Session() as session:
        product = session.execute(
            select(Product).where(Product.id == product_id)
        ).scalar_one()

        # Another request could modify stock here!
        if product.stock >= quantity:
            product.stock -= quantity
            session.commit()
        else:
            raise ValueError("Insufficient stock")

# GOOD - use SELECT FOR UPDATE
def decrement_stock(product_id: int, quantity: int):
    with Session() as session:
        with session.begin():
            product = session.execute(
                select(Product)
                .where(Product.id == product_id)
                .with_for_update()  # Row locked until commit
            ).scalar_one()

            if product.stock >= quantity:
                product.stock -= quantity
            else:
                raise ValueError("Insufficient stock")

# ASYNC version
async def decrement_stock(product_id: int, quantity: int):
    async with AsyncSession() as session:
        async with session.begin():
            result = await session.execute(
                select(Product)
                .where(Product.id == product_id)
                .with_for_update()
            )
            product = result.scalar_one()

            if product.stock >= quantity:
                product.stock -= quantity
            else:
                raise ValueError("Insufficient stock")
```

### 9. Using String-Based Filters Instead of Column Objects

**Problem**: No IDE support, error-prone, SQL injection risk.

```python
# BAD - string-based filters
def search_users(name: str):
    with Session() as session:
        users = session.execute(
            select(User).filter_by(name=name)  # String-based
        ).scalars().all()
        return users

# WORSE - string SQL (SQL injection risk!)
def search_users(name: str):
    with Session() as session:
        users = session.execute(
            f"SELECT * FROM users WHERE name = '{name}'"  # NEVER DO THIS!
        ).all()

# GOOD - column object filters
def search_users(name: str):
    with Session() as session:
        users = session.execute(
            select(User).where(User.name == name)  # Type-safe
        ).scalars().all()
        return users

# BETTER - parameterized for complex filters
from sqlalchemy import text

def search_users_complex(filters: dict):
    with Session() as session:
        query = select(User)
        if "name" in filters:
            query = query.where(User.name.contains(filters["name"]))
        if "active" in filters:
            query = query.where(User.active == filters["active"])

        users = session.execute(query).scalars().all()
        return users
```

### 10. Not Using Subqueries Efficiently

**Problem**: Multiple queries instead of single subquery.

```python
# BAD - multiple queries
def get_users_with_recent_posts():
    with Session() as session:
        # First query
        recent_post_user_ids = session.execute(
            select(Post.user_id)
            .where(Post.created_at > datetime.now() - timedelta(days=7))
            .distinct()
        ).scalars().all()

        # Second query
        users = session.execute(
            select(User).where(User.id.in_(recent_post_user_ids))
        ).scalars().all()
        return users

# GOOD - single query with subquery
def get_users_with_recent_posts():
    with Session() as session:
        recent_posts_subq = (
            select(Post.user_id)
            .where(Post.created_at > datetime.now() - timedelta(days=7))
            .distinct()
            .subquery()
        )

        users = session.execute(
            select(User).where(User.id.in_(select(recent_posts_subq.c.user_id)))
        ).scalars().all()
        return users

# BETTER - use join
def get_users_with_recent_posts():
    with Session() as session:
        users = session.execute(
            select(User)
            .join(Post)
            .where(Post.created_at > datetime.now() - timedelta(days=7))
            .distinct()
        ).scalars().all()
        return users
```

### 11. Not Using union/union_all

**Problem**: Multiple queries when one combined query would work.

```python
# BAD - multiple queries
def get_all_content():
    with Session() as session:
        posts = session.execute(select(Post)).scalars().all()
        pages = session.execute(select(Page)).scalars().all()
        return {"posts": posts, "pages": pages}

# GOOD - union query (if columns match)
from sqlalchemy import union_all

def get_all_content_items():
    with Session() as session:
        posts_query = select(
            Post.id,
            Post.title,
            Post.created_at,
            literal("post").label("type")
        )

        pages_query = select(
            Page.id,
            Page.title,
            Page.created_at,
            literal("page").label("type")
        )

        combined = union_all(posts_query, pages_query)
        result = session.execute(combined).all()
        return result
```

## Review Questions

1. Are all queries using SQLAlchemy 2.0 `select()` syntax not legacy `query()`?
2. Are bulk operations used for batch inserts/updates?
3. Are only required columns selected when full objects aren't needed?
4. Is `exists()` used instead of loading objects for existence checks?
5. Is pagination implemented for large result sets?
6. Is `with_for_update()` used for concurrent updates?
7. Are column objects used instead of string-based filters?

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.