Почему при создании таблицы Alembic требует указать длину для `varchar`, если она уже задана в модели?

Здравствуйте! Я пытаюсь создать таблицу с помощью команды alembic revision --autogenerate -m "create users table". Вот мой код: 

```python
from sqlalchemy import text, String
from sqlalchemy.orm import Mapped, mapped_column
from app.database import Base, str_uniq, int_pk

class User(Base):
    id: Mapped[int_pk]
    phone_number: Mapped[str_uniq] = mapped_column(String(length=100))  # Указана длина
    first_name: Mapped[str] = mapped_column(String(length=128))  # Указана длина
    last_name: Mapped[str] = mapped_column(String(length=128))  # Указана длина
    email: Mapped[str_uniq] = mapped_column(String(length=100))  # Указана длина
    password: Mapped[str] = mapped_column(String(length=255))  # Указана длина

    is_user: Mapped[bool] = mapped_column(default=True, server_default=text('true'), nullable=False)
    is_student: Mapped[bool] = mapped_column(default=False, server_default=text('false'), nullable=False)
    is_teacher: Mapped[bool] = mapped_column(default=False, server_default=text('false'), nullable=False)
    is_admin: Mapped[bool] = mapped_column(default=False, server_default=text('false'), nullable=False)
    is_super_admin: Mapped[bool] = mapped_column(default=False, server_default=text('false'), nullable=False)

    extend_existing = True

    def __repr__(self):
        return f"{self.__class__.__name__}(id={self.id})"
```

Наследуется:

```python
from datetime import datetime
from typing import Annotated

from sqlalchemy import func
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncAttrs
from sqlalchemy.orm import DeclarativeBase, declared_attr, Mapped, mapped_column
```

Можете помочь разобраться с созданием таблицы?
  • 9 января 2025 г. 6:23
Ответы на вопрос 1
Проблема, с которой вы столкнулись, скорее всего связана с тем, что Alembic не способен правильно интерпретировать аннотации `Mapped` и динамические типы, которые вы используете. В частности, при автоматической генерации миграции Alembic может не распознать точно, что означает `int_pk` и `str_uniq`, если они не определены в самом коде.

Чтобы Alembic смог правильно распознать типы, вам нужно убедиться, что:
1. `int_pk` и `str_uniq` определены как правильные типы SQLAlchemy, например, `Integer` и `String`, и не являются неопределенными типами.
2. Alembic может извлечь метаданные о таблице и типах колонок. Иногда это означает, что все классы и типы должны быть доступны в момент выполнения команды автогенерации.

Вот как это можно сделать:

1. **Проверьте определения `int_pk` и `str_uniq`:**
   Убедитесь, что `int_pk` и `str_uniq` определены как обычные типы SQLAlchemy. Например:

   ```python
   from sqlalchemy import Integer

   int_pk = Integer
   str_uniq = String(length=100)  # или просто String, если хотите указать длину позже
   ```

2. **Проверьте, что все необходимые импорты доступны:**
   Проверьте, что в том файле, где вы создаете миграцию, правильно импортированы все классы и метаданные. Убедитесь, что Alembic знает о вашей модели User.

3. **Попробуйте упростить модель:**
   Если ничего из вышеуказанного не помогает, попробуйте временно убрать `Mapped` и используйте стандартные аннотации SQLAlchemy, чтобы проверить, решит ли это проблему:

   ```python
   class User(Base):
       __tablename__ = 'users'
       id = mapped_column(Integer, primary_key=True)  # Укажите явные типы
       phone_number = mapped_column(String(length=100))
       first_name = mapped_column(String(length=128))
       last_name = mapped_column(String(length=128))
       email = mapped_column(String(length=100))
       password = mapped_column(String(length=255))
       ...
   ```

4. **Обновите alembic.ini:**
   Убедитесь, что в файле `alembic.ini` указан правильный путь к вашей базе данных и директория, в которой Alembic должен искать ваши модели.

После применения этих изменений снова запустите команду `alembic revision --autogenerate -m "create users table"` и посмотрите, устранена ли ошибка.
Похожие вопросы