> ## Documentation Index
> Fetch the complete documentation index at: https://codegeninc-codegen-bot-sdk-docs-2-0.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from SQLAlchemy 1.4 to 2.0

> Learn how to migrate SQLAlchemy 1.4 codebases to 2.0 using Codegen

Migrating from [SQLAlchemy](https://www.sqlalchemy.org/) 1.4 to 2.0 involves several API changes to support the new 2.0-style query interface. This guide will walk you through using Codegen to automate this migration, handling query syntax, session usage, and ORM patterns.

<Info>
  You can find the complete example code in our [examples repository](https://github.com/codegen-sh/codegen-sdk/tree/develop/codegen-examples/examples/sqlalchemy_1.4_to_2.0).
</Info>

## Overview

The migration process involves three main steps:

1. Converting legacy Query objects to select() statements
2. Updating session execution patterns
3. Modernizing ORM relationship declarations

Let's walk through each step using Codegen.

## Step 1: Convert Query to Select

First, we need to convert legacy Query-style operations to the new select() syntax:

```python
def convert_query_to_select(file):
    """Convert Query-style operations to select() statements"""
    for call in file.function_calls:
        if call.name == "query":
            # Convert query(Model) to select(Model)
            call.set_name("select")

            # Update method chains
            if call.parent and call.parent.is_method_chain:
                chain = call.parent
                if "filter" in chain.source:
                    # Convert .filter() to .where()
                    chain.source = chain.source.replace(".filter(", ".where(")
                if "filter_by" in chain.source:
                    # Convert .filter_by(name='x') to .where(Model.name == 'x')
                    model = call.args[0].value
                    conditions = chain.source.split("filter_by(")[1].split(")")[0]
                    new_conditions = []
                    for cond in conditions.split(","):
                        if "=" in cond:
                            key, value = cond.split("=")
                            new_conditions.append(f"{model}.{key.strip()} == {value.strip()}")
                    chain.edit(f".where({' & '.join(new_conditions)})")
```

This transforms code from:

```python
# Legacy Query style
session.query(User).filter_by(name='john').filter(User.age >= 18).all()
```

to:

```python
# New select() style
session.execute(
    select(User).where(User.name == 'john').where(User.age >= 18)
).scalars().all()
```

<Note>
  SQLAlchemy 2.0 standardizes on select() statements for all queries, providing
  better type checking and a more consistent API.
</Note>

## Step 2: Update Session Execution

Next, we update how queries are executed with the Session:

```python
def update_session_execution(file):
    """Update session execution patterns for 2.0 style"""
    for call in file.function_calls:
        if call.name == "query":
            # Find the full query chain
            chain = call
            while chain.parent and chain.parent.is_method_chain:
                chain = chain.parent

            # Wrap in session.execute() if needed
            if not chain.parent or "execute" not in chain.parent.source:
                chain.edit(f"execute(select{chain.source[5:]})")

            # Add .scalars() for single-entity queries
            if len(call.args) == 1:
                chain.edit(f"{chain.source}.scalars()")
```

This converts patterns like:

```python
# Old style
users = session.query(User).all()
first_user = session.query(User).first()
```

to:

```python
# New style
users = session.execute(select(User)).scalars().all()
first_user = session.execute(select(User)).scalars().first()
```

<Tip>
  The new execution pattern is more explicit about what's being returned, making
  it easier to understand and maintain type safety.
</Tip>

## Step 3: Update ORM Relationships

Finally, we update relationship declarations to use the new style:

```
```
