从jinja模板yaml文件加载django和sqlalchemy数据库fixture
Py-YAML-Fixtures的Python项目详细描述
py yaml固定装置
一个(work-in-progress)库,用于加载用Jinja2模板yaml文件编写的数据库装置。它支持faker和fixture对象之间的关系。目前它可以与以下软件包一起使用:
- Django 2+
- 烧瓶sqlalchemy
- 烧瓶未染色
- 独立的sqlalchemy
需要python 3.5+
有用链接
pip install py-yaml-fixtures
目录
fixture文件语法
fixme显示模型定义,清除有关文件夹的位
使用上面显示的Parent
和Child
模型作为示例,要用一些fixture数据填充这些模型,必须在PY_YAML_FIXTURES_DIR
中创建.yaml
(或.yml
)文件,该文件以每个模型的类名命名(在我们的例子中是Parent
和Child
)。例如:
# db/fixtures/Child.yamlalice:name:Alicebob:name:Bobgrace:name:Gracejudy:name:Judy
关系
顶级yaml键(alice
,bob
,grace
,judy
)是用于引用关系中对象的唯一id。它们在all模型装置中必须是唯一的。
为了引用它们,我们使用identifier字符串。标识符字符串由两部分组成:类名和一个或多个id。对于奇异关系,表示法是'ModelClassName(id)'
。对于关系的许多方面,符号是相同的,只是结合了yaml的列表语法:
# db/fixtures/Parent.yamlparent1:name:Parent 1children:['Child(alice)','Child(bob)']parent2:name:Parent 2children:-'Child(grace)'-'Child(judy)'# or in short-hand notationparent3:name:Parent 3children:['Child(alice,bob)']# technically, as long as there are at least 2 ids in the identifier string,# then even the YAML list syntax is optional, and you can write stuff like this:parent4:name:Parent 4children:Child(alice, bob)# or spanning multiple lines:parent5:name:Parent 5children:>Child(grace,judy,)
伪造者和金贾模板
所有的yaml fixtures文件在加载之前都由jinja呈现。这意味着您可以完全访问jinja环境,并可以使用诸如faker
、range
和random
:
# db/fixtures/Child.yaml {% for i in range(0, 20) %} child{{ i }}: name: {{ faker.name() }} {% endfor %}
# db/fixtures/Parent.yaml {% for i in range(0, 10) %} parent{{ i }}: name: {{ faker.name() }} children: {{ random_models('Child', 0, range(0, 4)|random) }} {% endfor %}
还有两个包含的jinja助手函数:
random_model(model_name: str)
- 例如,要获得一个随机的
Child
模型:{{ random_model('Child') }}
- 例如,要获得一个随机的
random_models(model_name: str, min_count: int = 0, max_count: int = 3)
- 例如,要获取0到3
Child
模型的列表:{{ random_models('Child') }}
- 例如,要获取1到4个
Child
模型的列表:{{ random_models('Child', 1, 4) }}
- 例如,要获取0到3
安装
# to use with django pip install py-yaml-fixtures[django]# to use with flask-sqlalchemy pip install py-yaml-fixtures[flask-sqlalchemy]# to use with flask-unchained pip install py-yaml-fixtures[flask-unchained]# to use with standalone sqlalchemy pip install py-yaml-fixtures[sqlalchemy]
配置
用Django
将py_yaml_fixtures
添加到settings.INSTALLED_APPS
中。
py_yaml_fixtures
应用程序添加一个命令:manage.py import_fixtures
。它会在您的settings.INSTALLED_APPS
文件夹中配置的每个应用程序中查找fixture文件。例如:
# example folder structure:# app project-root/app/fixtures/ project-root/app/fixtures/ModelOne.yaml # blog project-root/blog/fixtures/ project-root/blog/fixtures/ModelTwo.yaml # auth project-root/auth/fixtures/ project-root/auth/fixtures/ModelThree.yaml project-root/auth/fixtures/ModelFour.yaml
# project-root/your_app/settings.pyINSTALLED_APPS=[# ...'py_yaml_fixtures','app','blog','auth',]
要将模型装置加载到数据库中,您可以运行:
cd your-django-project-root # to load fixtures from all apps ./manage.py import_fixtures # or to load fixtures from specific apps ./manage.py import_fixtures app blog
与Flask和Flask-SQLAlchemy
这是使flask cli命令可用于导入设备所需的最小设置,默认情况下,flask import-fixtures
:
fromflaskimportFlaskfromflask_sqlalchemyimportSQLAlchemyfrompy_yaml_fixtures.flaskimportPyYAMLFixturesapp=Flask(__name__)db=SQLAlchemy(app)# optional configuration settings (these are all the defaults):app.config['FLASK_MODELS_MODULE']='app.models'app.config['PY_YAML_FIXTURES_DIR']='db/fixtures'app.config['PY_YAML_FIXTURES_COMMAND_NAME']='import-fixtures'fixtures=PyYAMLFixtures(app)
在配置的PY_YAML_FIXTURES_DIR
中创建fixture文件之后,就可以运行flask import-fixtures
将fixture加载到数据库中。
用Flask Unchained
将py_yaml_fixtures
添加到unchained_config.BUNDLES
中。
pyyamlfixtures包向flask添加一个未受约束的命令:flask db import-fixtures
。它在每个包的{{CD29>}文件夹中查找固定文件(如果存在)。例如:
# example folder structure:# app project-root/app/fixtures/ project-root/app/fixtures/ModelOne.yaml # blog_bundle project-root/bundles/blog/ project-root/bundles/blog/Post.yaml # security_bundle project-root/bundles/security/ project-root/bundles/security/User.yaml project-root/bundles/security/Role.yaml
# project-root/unchained_config.pyBUNDLES=[# ...'flask_unchained.bundles.sqlalchemy','py_yaml_fixtures','bundles.security','app',]
要将模型装置加载到数据库中,您可以运行:
cd your-flask-unchained-project-root # to load fixtures from all bundles flask db import-fixtures # or to load fixtures from specific bundles flask db import-fixtures app security_bundle
独立的{a26}
importsqlalchemyassafrompy_yaml_fixturesimportFixturesLoaderfrompy_yaml_fixtures.factories.sqlalchemyimportSQLAlchemyModelFactoryfromsqlalchemyimportcreate_enginefromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy.ormimportrelationship,sessionmakerPY_YAML_FIXTURES_DIR='db/fixtures'BaseModel=declarative_base()classParent(BaseModel):id=sa.Column(sa.Integer,primary_key=True)name=sa.Column(sa.String)children=relationship('Child',back_populates='parent')classChild(BaseModel):id=sa.Column(sa.Integer,primary_key=True)name=sa.Column(sa.String)parent_id=sa.Column(sa.Integer,sa.ForeignKey('parent.id'))parent=relationship('Parent',back_populates='children')# first we need a list of our model classes to provide to the factorymodels=[Parent,Child]# and we need a session connected to the database, also for the factoryengine=create_engine('sqlite:///:memory:')Session=sessionmaker()Session.configure(bind=engine)session=Session()# then we create the factory, and pass it to the fixtures loaderfactory=SQLAlchemyModelFactory(session,models)loader=FixturesLoader(factory,fixture_dirs=[PY_YAML_FIXTURES_DIR])# to create all the fixtures in the database, we have to call loader.create_all()if__name__=='__main__':loader.create_all(lambdaidentifier,model,created:print('{action}{identifier}: {model}'.format(action='Creating'ifcreatedelse'Updating',identifier=identifier.key,model=repr(model))))
贡献
欢迎投稿!
- 请将错误报告作为github问题提交。
- 或者更好的是,打开一个带有修复的拉取请求!
添加对其他orms的支持
必须通过扩展py_yaml_fixtures.FactoryInterface
来实现具体工厂。必须实现三个抽象方法:create_or_update
、get_relationships
和maybe_convert_values
(请参见DjangoModelFactory和SQLAlchemyModelFactory实现示例)。
许可证
麻省理工学院