【问题标题】:sqlalchemy: alembic bulk insert fails: 'str' object has no attribute '_autoincrement_column'sqlalchemy:alembic 批量插入失败:“str”对象没有属性“_autoincrement_column”
【发布时间】:2013-03-21 11:44:49
【问题描述】:

我的模型看起来像

class Category(UserMixin, db.Model):
    __tablename__ = 'categories'
    uuid = Column('uuid', GUID(), default=uuid.uuid4, primary_key=True,
                  unique=True)
    name = Column('name', String, nullable=False)
    parent = Column('parent', String, nullable=False)
    created_on = Column('created_on', sa.types.DateTime(timezone=True),
                        default=datetime.utcnow())
    __table_args__ = (UniqueConstraint('name', 'parent'),)

    def __init__(self, name, parent):
        self.name = name
        self.parent = parent

    def __repr__(self):
        return '<Category:%s:%s:%s>' % (
            self.uuid, self.name, self.category_type)

GUID 是自定义 sqlalchemy 类型 我使用alembic --autogenerate 选项创建表

 op.create_table('categories',
                    sa.Column('uuid', UUID(), nullable=False),
                    sa.Column('name', sa.String(), nullable=False),
                    sa.Column('parent', sa.String(), nullable=False),
                    sa.Column('created_on', sa.DateTime(timezone=True),
                              nullable=True),
                    sa.PrimaryKeyConstraint('uuid'),
                    sa.UniqueConstraint('name', 'parent'),
                    sa.UniqueConstraint('uuid')
    )

和PostgreSQL表一样

            Table "public.categories"
   Column   |           Type           | Modifiers
------------+--------------------------+-----------
 uuid       | uuid                     | not null
 name       | character varying        | not null
 parent     | character varying        | not null
 created_on | timestamp with time zone |
Indexes:
    "categories_pkey" PRIMARY KEY, btree (uuid)
    "categories_name_parent_key" UNIQUE CONSTRAINT, btree (name, parent)

我尝试运行修订版并将数据库更新为

def upgrade():
    op.bulk_insert('categories',
                   [
                       {'name': 'first', 'parent': 'first_parent'},
                       {'name': 'second', 'parent': 'second_parent'}
                   ]
    )

当我运行 alembic upgrade head 时,我看到错误为

  File "/Users/me/.virtualenvs/envs/project/lib/python2.7/site-packages/alembic/environment.py", line 494, in run_migrations
    self.get_context().run_migrations(**kw)
  File "/Users/me/.virtualenvs/envs/project/lib/python2.7/site-packages/alembic/migration.py", line 211, in run_migrations
    change(**kw)
  File "alembic/versions/491d4f91e0bc_generate_categories_.py", line 21, in upgrade
    {'name': 'second', 'parent': 'second_parent'}
  File "<string>", line 7, in bulk_insert
  File "/Users/me/.virtualenvs/envs/project/lib/python2.7/site-packages/alembic/operations.py", line 710, in bulk_insert
    self.impl.bulk_insert(table, rows)
  File "/Users/me/.virtualenvs/envs/project/lib/python2.7/site-packages/alembic/ddl/impl.py", line 179, in bulk_insert
    table._autoincrement_column = None
AttributeError: 'str' object has no attribute '_autoincrement_column'

我在这里做错了什么?

【问题讨论】:

    标签: python postgresql sqlalchemy alembic


    【解决方案1】:

    我所要做的就是在 bulk_insert 之前创建一个 table,即使我在单独的 models.py 中有一个明确的架构

    import sqlalchemy as sa
    from sqlalchemy.sql import table
    from alembic import op
    
    def upgrade():
         categories = table('categories',
                           sa.Column('uuid', UUID(),
                                  primary_key=True,
                                  unique=True, autoincrement=False),
                           sa.Column('name', String),
                           sa.Column('parent', String),
                           sa.Column('created_on', sa.types.DateTime(timezone=True),
                                  default=datetime.utcnow())
        )
        op.bulk_insert(categories,
                       [
                           {'name': 'first', 'parent': 'first_parent'},
                           {'name': 'second', 'parent': 'second_parent'}
                       ]
        )
    

    然后我能够毫无问题地运行alembic upgrade head,并且数据在数据库中成功序列化。

    【讨论】:

    • 请注意,这使用sqlalchemy.sql.table alembic.op.create_table。我花了一段时间才意识到create_table 没有返回任何东西。此外,bulk_insert 的第一个参数是table 实例,而不是str
    • 请注意,@Jon 的评论不再相关。 op.create_table 返回自版本 0.7.0 以来的表对象。 alembic.readthedocs.org/en/latest/…
    • 那么您不需要在修订文件中创建表。你可以刚刚完成category_table = my.project.models.categories.__table__
    猜你喜欢
    • 2019-10-13
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 2015-09-11
    • 2014-05-28
    • 2016-09-20
    相关资源
    最近更新 更多