尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Django 如何预置应用初始数据:数据迁移与 fixtures 两种做法

Django 如何预置应用初始数据:数据迁移与 fixtures 两种做法 Django 如何预置应用初始数据数据迁移与 fixtures 两种做法【免费下载链接】djangoThe Web framework for perfectionists with deadlines.项目地址: https://gitcode.com/GitHub_Trending/dj/django搭建 Django 应用时数据库初始往往是空的但演示环境、种子数据或基础配置常常需要在建库的同时就有数据可查。Django 官方文档docs/howto/initial-data.txt给出了两条路径用数据迁移data migration让数据随migrate自动加载或用fixtures文件配合dumpdata/loaddata命令手动导入。本文基于 migrations 文档、序列化文档 和 管理命令文档 说明两种做法的具体操作、查找规则与各自的限制前提是你已完成migrate的基础配置并跑通过python manage.py migrate。两种做法的适用差异先看清文档给出的关键区别再选路径数据迁移migrate时自动执行属于版本化流程的一部分文档同时说明迁移在搭建测试数据库时也会被运行所以测试数据库里同样能用到这份数据。适合每次全新环境都应带上的固定数据。fixtures文档明确指出这类数据不会自动加载例外是测试框架中TransactionTestCase.fixtures的用法。每次需要时手动执行loaddata并且重复执行会把 fixture 内容重新写回数据库冲掉期间对这批行做过的修改。适合按需导入、可重复覆盖的数据。做法一用数据迁移预置初始数据创建一个空迁移文件Django 不会像 schema 迁移那样自动生成数据迁移但流程很直接先建一个空迁移文件Django 会把它放到正确位置、给出文件名并补上依赖python manage.py makemigrations --empty yourappname把yourappname换成你要存放初始数据的实际应用名。生成的文件大致长这样# Generated by Django A.B on YYYY-MM-DD HH:MM from django.db import migrations class Migration(migrations.Migration): dependencies [ (yourappname, 0001_initial), ] operations []用 RunPython 写入数据数据迁移的核心操作是migrations.RunPython。它接收一个可调用对象两个参数第一个是app registry加载了与当前迁移位置匹配的历史版本模型第二个是SchemaEditor。文档强调不要直接 import 模型——迁移执行时模型可能已是新版本——而要用apps.get_model()取历史版本。下面沿用文档示例把新加的name字段填充为first_name和last_name的拼接值同样的写法可用于写入任意固定行用Person.objects.create(...)之类的调用即可from django.db import migrations def combine_names(apps, schema_editor): # We cant import the Person model directly as it may be a newer # version than this migration expects. We use the historical version. Person apps.get_model(yourappname, Person) for person in Person.objects.all(): person.name f{person.first_name} {person.last_name} person.save() class Migration(migrations.Migration): dependencies [ (yourappname, 0001_initial), ] operations [ migrations.RunPython(combine_names), ]执行并验证写完后照常运行python manage.py migrate数据迁移会在这个命令中随其他迁移按序执行执行完数据库里即有对应数据。验证方式就是查库迁移跑完后直接查询目标表/模型确认数据存在或跑项目的测试用例迁移在测试数据库搭建时也会执行文档提示测试环境下存在若干限制。两个文档明确给出的注意点反向迁移可以给RunPython传第二个可调用对象定义回滚逻辑如果不传回退迁移时会直接抛异常。也就是说预置数据的迁移默认不能安全地往回migrate。跨应用取模型如果RunPython函数要用到其他应用的模型dependencies里必须包含这些应用各自的最新迁移否则通过apps.get_model()取模型时会遇到类似LookupError: No installed app with label myappname的错误。文档示例class Migration(migrations.Migration): dependencies [ (app1, 0001_initial), # added dependency to enable using models from app2 in move_m1 (app2, 0004_foobar), ]做法二用 fixtures 预置初始数据创建 fixture 文件fixture 是 Django 能导入数据库的一组数据支持 JSON、XML、YAML 三种格式YAML 需要安装 PyYAML。文档给出的Person模型示例如下JSON文档示例[ { model: myapp.person, pk: 1, fields: { first_name: John, last_name: Lennon } }, { model: myapp.person, pk: 2, fields: { first_name: Paul, last_name: McCartney } } ]同一份数据写成 YAML 就是- model: myapp.person pk: 1 fields: first_name: John last_name: Lennon - model: myapp.person pk: 2 fields: first_name: Paul last_name: McCartney各格式的字段细节外键用 pk 表示、多对多序列化给定义方等见 序列化文档。另一种更省事的路径库里已有数据时用dumpdata命令导出其输出可以直接作为loaddata的输入python manage.py dumpdata存放位置与查找规则文档规定把 fixture 存放在应用的fixtures目录内查找规则是默认在每个应用的fixtures目录中查找执行loaddata sample会找到my_app/fixtures/sample.json相对路径同样有效loaddata my_app/sample找到my_app/fixtures/my_app/sample.jsonDjango 还会在FIXTURE_DIRS设置列出的目录中查找要完全禁用上述默认查找用绝对路径指定 fixture 文件位置例如loaddata /path/to/sample。文档专门提醒命名冲突loaddata使用第一个匹配到的同名文件不同应用里若存在同名 fixture 就无法区分。最简单的解决办法是给 fixture 文件做命名空间——放进以应用名命名的子目录即上面相对路径示例的写法。加载与验证执行加载python manage.py loaddata fixturenamefixturename就是你创建的 fixture 文件名不带扩展名或用带路径的名字。执行后数据即进入数据库可查询对应模型确认。文档还给出了从标准输入读取的用法需指定--format以及跨库导出的管道示例django-admin dumpdata --formatjson --databasetest app_label.ModelName | django-admin loaddata --formatjson --databaseprod -必须知道的限制覆盖行为每次运行loaddata都会把 fixture 中的行重新写回数据库。如果你修改过其中某一行再跑一次所做的修改会被冲掉。不要包含自动生成的对象序列化文档警告永远不要把 Django 自动创建的对象如auth.Permission、Group、ContentType等写进 fixture——pk 恰好匹配时加载无效不匹配时则可能以IntegrityError失败。不会自动执行fixtures 只在显式loaddata或测试框架的TransactionTestCase.fixtures时加载不能指望它随部署自动发生需要自动化的场景回到做法一。收尾按目标二选一两条路径的操作终点都是同一个判断全新环境下跑完对应命令migrate或loaddata后初始数据已经可用。要求环境初始化即可得到数据、且数据随版本演进时用数据迁移并要求可回滚时补上第二个可调用对象数据量大、需要按需导入或反复重置时用 fixtures 并注意loaddata的覆盖语义。更多格式细节可继续阅读 docs/topics/serialization.txtdumpdata/loaddata的完整选项见 docs/ref/django-admin.txt。【免费下载链接】djangoThe Web framework for perfectionists with deadlines.项目地址: https://gitcode.com/GitHub_Trending/dj/django创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表