在 python 金字塔 web 框架中,如何在播种之前删除所有数据库表行?

Posted

技术标签:

【中文标题】在 python 金字塔 web 框架中,如何在播种之前删除所有数据库表行?【英文标题】:In python pyramid web framework, how can I drop all db table rows before seeding? 【发布时间】:2021-11-11 00:02:06 【问题描述】:

我正在使用 cookiecutter 制作金字塔网络应用程序。 它具有在此处播种数据库的功能: https://github.com/Pylons/pyramid-cookiecutter-starter/blob/latest/%7B%7Bcookiecutter.repo_name%7D%7D/%7B%7Bcookiecutter.repo_name%7D%7D/sqlalchemy_scripts/initialize_db.py#L15

但是如果我运行它两次,或者更改我添加的条目,我会得到重复的条目和错误。我正在使用带有 sqlalchemy 的 sqlite 数据库。

我可以在setup_models 中添加什么代码,在编写新模型实例之前删除所有 db 行? 如果这会遍历所有模型并删除它们的所有实例,那就太好了。

def setup_models(dbsession):
    """
    Add or update models / fixtures in the database.
    """
    model = models.mymodel.MyModel(name='one', value=1)
    dbsession.add(model)

我正在通过运行更新数据库:

# to run the initial migration that adds the tables to the db, run this once
venv/bin/alembic -c development.ini upgrade head
# seed the data, I want to be able to keep editing the seed data
# and re-run this command and have it will wipe the db rows and insert the seed data defined in setup_models
venv/bin/initialize_suppah_db development.ini

【问题讨论】:

使用 Alembic 进行数据库迁移:alembic.sqlalchemy.org/en/latest。 Pyramid SQL/URL Dispatch 教程中描述了 cookiecutter 的示例用法:docs.pylonsproject.org/projects/pyramid/en/latest/tutorials/… 这不是分层迁移插入数据,这是我们只使用初始种子数据的时候。我不想通过迁移来做到这一点。我按照这些步骤在创建 deb 表的位置进行迁移,然后运行命令为调用 setup_models 的数据库播种。 我在问题中添加了我的 alembic 调用详细信息 您是否使用Alembic?如果您不想使用它,那么您可以从文件系统中删除 SQLite 数据库文件并重新运行您的 db ini 脚本。 删除所有行并保留表架构 【参考方案1】:

默认情况下,SQLite 不会在引擎级别强制执行外键约束(即使您已经在表 DDL 中声明了它们),因此您可能只使用像这样简单的东西

insp = inspect(engine)
with engine.begin() as conn:
    for table_name in insp.get_table_names():
        conn.exec_driver_sql(f'DELETE FROM "table_name"')

【讨论】:

您好,我要求提供可以添加到上述 setup_models 函数的代码。能否包含所需的导入并将其包含在 setup_models 函数中?【参考方案2】:

可以通过以下方式做到这一点:

循环遍历所有模型类 将这些类的所有实例都删除 提交会话/事务以删除它们 然后播种数据 下面的代码就是这样做的:
import transaction
from ..models.meta import Base

def delete_table_rows(dbsession):
    model_clases = [cls for cls in Base.__subclasses__()]
    with transaction.manager as tx:
        for model_clases in model_clases:
            for instance in dbsession.query(model_clases).all():
                dbsession.delete(instance)
        transaction.commit()


def setup_models(dbsession):
    """
    Add or update models / fixtures in the database.

    """
    delete_table_rows(dbsession)
    # your custom seed code here
    model = models.mymodel.MyModel(name='one', value=1)
    dbsession.add(model)

【讨论】:

以上是关于在 python 金字塔 web 框架中,如何在播种之前删除所有数据库表行?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Anaconda Jupyter 笔记本上运行金字塔自动 arima?

[Python从零到壹] 四十二.图像处理基础篇之图像金字塔向上取样和向下取样

如何从 iOS 应用程序调用在 Python 的 ladon 框架中开发的 Web 服务?

金字塔网络框架中可能存在的奇怪错误

Python Web 框架、WSGI 和 CGI​​ 如何组合在一起

如何在Python Flask框架中运行重复任务