testcontainers / testcontainers/testcontainers-python
Feature: Seed data for DbContainer
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 2.3k
- 派生
- 386
- 平均合并
- 4 小时 40 分钟
- 30 天内合并 PR
- 1
描述
What are you trying to do?
In order to do meaningful tests using my fresh database, I wish to load arbitrary SQL scripts from my DbContainer-s.
I can do (and have done) this per-project, in test folders, but believe there's value in allowing an arbitrary list of SQL scripts to be run before the testcontainer is yielded, and making this a pytest fixture to reuse.
I do this usually by first passing a path to a folder with scripts, volume-mount it to /seeds path in the database container, and also pass a list of script files in that folder to be executed. Then before yielding the ready db-container, I loop over each script filename and do container.exec_run(["mysql", "-e" f"source /seeds/{script}").
The list of scripts means we can feed both schema first, then arbitrary sample data files.
I suggest a new DbContainer._seed() method, defaulting to raise NotImplementedError, to be overriden per database, allowing a new optional parameter seed.
Each database then just has to define their _seed() function to the specific way to exec_run the scripts (psql for Postgres, mysql for MySQL CLI...)
Example from #542 implementation draft:
>>> import sqlalchemy
>>> from testcontainers.mysql import MySqlContainer
>>> seed_data = ("db/", ["schema.sql", "data.sql"])
>>> with MySqlContainer(seed=seed_data) as mysql:
... engine = sqlalchemy.create_engine(mysql.get_connection_url())
... with engine.begin() as connection:
... query = "select * from stuff" # Can now rely on schema/data
... result = connection.execute(sqlalchemy.text(query))
... first_stuff, = result.fetchone()
Why should it be done this way?
I believe most users of testcontainers, beyond just testing connectivity with a database, want a simple-to-reproduce test environment with realistic datastructure and mock data. This is currently annoying to do locally, and can be upstreamed into a simple-looking seed parameter, which could enable the feature for most databases, by pushing it into DbContainer itself.
See #542 for a draft implementation using MySQL as target (generalizeable to others of course)
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 #542 的草稿实现以及这里描述的 DbContainer 和 MySqlContainer 入口开始。梳理提议的 seed 元组、特定于数据库的 _seed() 方法和可复用的 pytest fixture 将如何配合。完成的标准是:示例能够在返回容器之前加载 schema.sql 和 data.sql,并且该方法能够推广到 MySQL 之外。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- docker, mysql, postgresql, python, sql
- 领域
- database, testing
- Issue 类型
- 功能
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100