Search code examples
python-2.7sqlalchemytornadoalembic

Integrating tornado (4.4.1), sqlalchemy (1.1.0) and alembic (0.8.7) in Python 2.7


I am writing my first Python web application, and I want to use alembic for handling the migrations. So far I have done this (just pointing out the imp. files) and it doesn't seem to work.

Project structure:

project/
    alembic.ini
    alembic/
        versions/
            3cd4a4f9cdef_create_users_table.py
    models/
        __init__.py
        base.py
        users.py

3cd4a4f9cdef_create_users_table.py

"""create users table

Revision ID: 3cd4a4f9cdef
Revises:
Create Date: 2016-09-07 13:54:25.705084

"""

# revision identifiers, used by Alembic.
revision = '3cd4a4f9cdef'
down_revision = None
branch_labels = None
depends_on = None

from alembic import op
import sqlalchemy as sa


def upgrade():
    op.create_table(
        'users',
        Column('id', sa.Integer, primary_key=True),
        Column('name', sa.String(256), nullable=False)
    )


def downgrade():
    op.drop_table('users')

__init__.py

from sqlalchemy import create_engine
from sqlalchemy.sql import select
from users import User

engine = create_engine('sqlite:///:memory:', echo=True)

base.py

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

users.py

from base import Base

class User(Base):

    user_table = 'users'
    __table__ = user_table

    id = user_table.c.id
    name = user_table.c.name

$ python models/__init__.py throws this error:

Traceback (most recent call last):
  File "models/__init__.py", line 3, in <module>
    from users import User
  File "/Users/sudeep.agarwal/src/project/models/users.py", line 5, in <module>
    class Asset(Base):
  File "/Users/sudeep.agarwal/src/squiddy/models/users.py", line 10, in Asset
    id = asset_table.c.id
AttributeError: 'str' object has no attribute 'c'

I don't want to do this in users.py as it would mean duplication of schema definition:

from base import Base
from sqlalchemy import Column

class User(Base):

    __table__ = 'users'

    id = Column('id', Integer, primary_key=True)
    name = Column('name', String, nullable=False)

What is the cleanest way to achieve this?


Solution

  • Frankly, I do not quite understand what you're trying to do. But some parts of code looks completely wrong. Why have you two definitions of User? What are you trying to achieve with id = user_table.c.id? I can only guess. At first, define somewhere table schema:

    metadata = MetaData()
    users_schema = Table('users', metadata,
        Column('id', Integer, primary_key=True),
        Column('name', String, nullable=False)
    )
    

    Then you can use it to define the model:

    class User(Base):
        __table__ = users_schema
    

    Or you can define the model directly:

    class User(Base):
        __tablename__ = 'users'
    
        id = Column('id', Integer, primary_key=True)
        name = Column('name', String, nullable=False)
    

    And you do not need to redefine it in other files. Only import it and use.