当前位置: 首页 > news >正文

网站制作的流程包括恶意点击竞价是用的什么软件

网站制作的流程包括,恶意点击竞价是用的什么软件,杭州网站开发公司排名,ueeshop建站靠谱吗TL;DR 永远不要相信 makemigrations! migrate 之前一定好好看看 migrate 了啥东西,必要时手动修改生成的 migrate 文件。 最好把db的更新与服务代码更新解耦 场景 先描述下场景: 现在有两个表,一个是 question,一…

TL;DR

永远不要相信 makemigrations!

migrate 之前一定好好看看 migrate 了啥东西,必要时手动修改生成的 migrate 文件。

最好把db的更新与服务代码更新解耦

场景

先描述下场景:

现在有两个表,一个是 question,一个是 choice,其中 question 和 choice 是一对多的关系,其中 choice 表中会记录 question_id(此时不是外键约束)。

class Question(models.Model):content = models.CharField(max_length=256, blank=True, default='')class Choice(models.Model):content = models.CharField(max_length=256, default='')question_id = models.IntegerField(null=True)

现在我想把 question_id 改为外键,所以很自然的改写 model:

class Question(models.Model):content = models.CharField(max_length=256, blank=True, default='')class Choice(models.Model):content = models.CharField(max_length=256, default='')question = models.ForeignKey(Question, on_delete=models.DO_NOTHING) 

然后快乐地执行 makemigration -> migrate,然后 choice 里面的 question_id 就全没了(实际上我还手贱加了个 default,导致都关联到 default 的 question 上了),然后第二天因为左脚先进办公室被开了。。。

原因

在自己的 demo 上复现了下。

问题出在 makemigrate 生成的文件上,解析出来的 operations 是先把 question_id 列 remove 掉(RemoveField),然后再加上(AddField)。。。

这样设计的思路我不是很懂,可能是有些 engine(比如SQLite)不支持对现有的表加外键?

解决

修改 migration 文件,把先 remove 再 add 的逻辑调整一下。

需要用到 migration.RunPython,migration 文件应该长成下边这样:

from django.db import migrations, models
import django.db.models.deletiondef duplicate_question_id(apps, schema_editor):Choice = apps.get_model("polls", "Choice")for c in Choice.objects.all():Question = apps.get_model("polls", "Question")q = Question.objects.get(id=c.question_id)c.question_cpy = qc.save()class Migration(migrations.Migration):# 一些必要的依赖,这里大概率不用改dependencies = []operations = [migrations.AddField(model_name="choice",name="question_cpy",# question_cpy 先把 question_id 列的数据 copy 过来field=models.ForeignKey(null=True,on_delete=django.db.models.deletion.DO_NOTHING,to="polls.question",),),migrations.RunPython(code=duplicate_question_id,reverse_code=migrations.RunPython.noop,# reverse_code 是 migrate 回退时会执行的操作# noop 方法是为了支持回退的空方法),migrations.RemoveField(model_name="choice",name="question_id",),migrations.RenameField(model_name="choice",old_name="question_cpy",new_name="question",),]

注意:你需要根据实际情况编写合适的代码,上面仅提供思路。

如果你是在sqlite上测试,可以正常 migrate,但是外键不会生效(因为 sqlite 默认关闭外键)。

如果在 mysql 上测试,应该是可以成功的(待验证)。

除了 RunPython 之外还可以用RunSQL,然后仔细确定SQL的合法性,个人感觉会更安全一些,毕竟直接操作 DB 的部分,普遍会认为潜在风险较高,会对相应动作有更高的敏感度。(不过最关键的还是要感知 makemigrations 其实不是个靠谱的东西)

又跟了下这个问题,发现在 AlterField 里面指定外键的 db_column,然后再 rename 成 model 里面指定的 name 即可实现上述需求,类似:

		migrations.AlterField(model_name="choice",name="question_id",field=models.ForeignKey(name='question',to='polls.question',on_delete=django.db.models.deletion.DO_NOTHING,db_column='question_id',null=False),),migrations.RenameField(model_name="choice",old_name="question_id",new_name="question",)

这里还有些需要注意的地方,migration 整体上是通过 DDL 事务执行的,但是有些 SQL 引擎不支持DDL 事务(比如 MySQL),所以可能会出现 migrate 不成功然后无法回滚的情况(一个 migration 可能会对应两条 SQL 语句),需要关注。

避免

永远不要相信 makemigrations!

最好把db的更新与服务代码更新解耦

Django 还提供了 sqlmigrate 这个命令,可以看对应的 migrations 动作具体会解析成哪些 sql 语句执行,可以在 merge 之前把对应的 sql 语句进行一次 review。

推荐

migrate 其实分 code state 和 db state 两部分,可以把这两部分开设置:change field name with no db impact

http://www.ds6.com.cn/news/71754.html

相关文章:

  • 广告设计图片用什么软件windows优化大师卸载
  • 有哪些做包装盒的网站热搜榜百度一下你就知道
  • wordpress所见即所得陕西seo推广
  • dw做网站后台图们网络推广
  • 太原网站建设 thinkphp3.2百家号关键词排名优化
  • 广州网站建设大公司广州seo网站推广优化
  • web盒子模型输出图片对联排名优化关键词公司
  • 汕头高端网站开发seo排名工具给您好的建议下载官网
  • 电影网站怎么做不犯法百度怎么注册自己的网站
  • 重庆百姓网长春网站seo公司
  • 做网店好还是网站好宁波seo网络推广报价
  • 手机网站设计要素电商seo是指
  • 做网站在经营范围内属于什么网站建设的数字化和互联网化
  • 网站计数器代码js百度大数据预测平台
  • 国外出名设计网站有哪些南京网站推广公司
  • 做博物馆网站最重要宁波网站推广找哪家
  • 做网站应该注意哪些方面网页宣传
  • wordpress底部导航栏插件搜索排名优化策划
  • 关于教做鞋的网站医院网站建设方案
  • 响应式网站开发图标搜狗网页搜索
  • 网站服务器租用需要注意的点网络营销的策划方案
  • wordpress 中文 主题乐陵seo外包
  • 招聘做网站专业人员黄金网站app大全
  • 百度网站入口特效词网络推广员招聘
  • 网站开发便宜网站seo快速优化
  • 企业网站优化系统推送者seo
  • 什么是网站运营中国联通业绩
  • 做app网站的公司哪家好百度搜索seo
  • 一个空间可以做多少个网站百度2022年版本下载
  • 秦皇岛建设管理中心网站外链在线发布工具