首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Flask-Migrate/Flask-SQLAlchemy中正确编辑Alembic迁移脚本以添加或编辑列?

如何在Flask-Migrate/Flask-SQLAlchemy中正确编辑Alembic迁移脚本以添加或编辑列?
EN

Stack Overflow用户
提问于 2019-12-25 18:08:14
回答 1查看 1.8K关注 0票数 1

我有一个小应用程序,我正在用它从在线文章中抓取数据。

目前,我正在试图弄清楚如何从Flask-migrate中编辑迁移脚本,这样我就不必删除所有迁移数据和SQlite数据库,然后在每次编辑模式时重新抓取数据!

当然,当我编辑模型、删除所有内容、重新初始化并再次抓取数据时,数据库可以很好地适应。但当我尝试手动编辑它时,它会运行升级,但我看不到数据有任何变化。

下面的例子...

迁移脚本:

代码语言:javascript
复制
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('article', sa.Column('example', sa.DateTime(), nullable=True))
    # ### end Alembic commands ###

我还尝试添加此列来填充数据,但当然没有成功,因为该列不存在(如果我遗漏了什么,请纠正我):

代码语言:javascript
复制
from datetime import datetime

...
def upgrade():
...
     op.execute("UPDATE article SET example = datetime.utcnow()")  # (new scraped data would get a new
                                                                   # timestamp but this would be fine
                                                                   # for old data for my purposes)

我对SQL和它的框架还很陌生,但为了以防万一,我在使用和不使用索引的情况下都做了这两件事。无论哪种情况,升级似乎都运行得很好:

代码语言:javascript
复制
(venv) Files\app> flask db upgrade
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade 2177b1c9ee45 -> 6c61158ea270, empty message
(venv) Files\app>

但是当我使用Flask-SQLAlchemy在命令行上查询时:

代码语言:javascript
复制
>>> from app.models import Article
>>> arts = Article.query.all()
>>> arts[0]
<Example Article: "Title" (2018)>       ##(Valid __repr__ of the model)
>>> arts[0].time_added
datetime.datetime(2019, 12, 25, 9, 23, 43, 331296)    ##(achieved this by deleting and restarting db from scratch)
>>> arts[0].example
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Article' object has no attribute 'example'
>>>

我不知道升级出了什么问题,但肯定有问题,因为降级给了我一个错误:

代码语言:javascript
复制
INFO  [alembic.runtime.migration] Running downgrade 6c61158ea270 -> 2177b1c9ee45, empty message
Traceback (most recent call last):
  File "c:\desktop\projects\site\app\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1246, in _execute_context
    cursor, statement, parameters, context
...
  File "c:\desktop\projects\site\app\venv\lib\site-packages\sqlalchemy\engine\default.py", line 581, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) near "DROP": syntax error
[SQL: ALTER TABLE article DROP COLUMN example]

降级函数非常简单,因此必须从未创建过该列:

代码语言:javascript
复制
def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('article', 'example')
    # ### end Alembic commands ###

有人能帮我了解一下如何在Flask-migrate迁移脚本中使用Alembic来定制数据库升级吗?

或者,我使用op.execute("UPDATE table SET column = values")的方式有问题吗

谢谢!

编辑:

忘了提一下,这里是模型中的代码行:

代码语言:javascript
复制
    example = db.Column(db.DateTime, default=datetime.utcnow())

此外,手动更改升级和降级也没有效果:

代码语言:javascript
复制
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    # ### end Alembic commands ###
    op.execute('UPDATE article SET example = datetime.utcnow()')

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.execute('UPDATE article SET example=Null')
    # ### end Alembic commands ###

其他编辑:

代码语言:javascript
复制
from app.models import set_time ### (set_time is just datetime.utcnow() but I
                                ### thought it might work to import it
                                ### from elsewhere -- it didn't

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    # ### end Alembic commands ###
    op.execute("UPDATE 'article' SET 'example' = VALUES (?)", (set_time))  #*

### (*Importing set_time from elsewhere 

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.execute("UPDATE 'article' SET 'example'=Null")
    # ### end Alembic commands ###

我一直收到这个错误:

代码语言:javascript
复制
TypeError: execution_options() argument after ** must be a mapping, not str

似乎一定有一种格式可以将Python变量传递到Alembic SQL查询中,但我并不知道。现在开始搜索。

另一个编辑(很抱歉这么多人):

下面的代码只是告诉我article (表名)是未定义的。对语法有帮助吗?

代码语言:javascript
复制
connection = op.get_bind()

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    # ### end Alembic commands ###
    connection.execute(
        article.update().values({"example": set_time})
    )

任何想法都非常感谢!

-Pete

EN

回答 1

Stack Overflow用户

发布于 2019-12-25 18:30:46

如果迁移已经解决,你更新没有问题,但是列还没有创建,我会亲自手动将它添加到sqlite数据库中,这样它就可以正常运行,没有问题,这些错误有时会发生在sqlite上。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59477297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档