有时,需要进行数据迁移.随着时间的推移,使用域模型的代码更改和迁移不再有效,迁移失败.迁移数据的最佳做法是什么?
我试过一个例子来澄清问题:
考虑一下.你有一个迁移
class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
def up
User.all.each do |user|
user.applied_at = user.partner_application_at
user.save
end
end
Run Code Online (Sandbox Code Playgroud)
当然,这完全没问题.稍后,您需要更改架构
class AddAcceptanceConfirmedAt < ActiveRecord::Migration
def change
add_column :users, :acceptance_confirmed_at, :datetime
end
end
class User < ActiveRecord::Base
before_save :do_something_with_acceptance_confirmed_at
end
Run Code Online (Sandbox Code Playgroud)
对你来说没问题.它完美运行.但是,如果您的同事今天同时进行了这两项迁移,但尚未运行第一次迁移,那么在运行第一次迁移时会出现此错误:
rake aborted!
An error has occurred, this and all later migrations canceled:
undefined method `acceptance_confirmed_at=' for #<User:0x007f85902346d8>
Run Code Online (Sandbox Code Playgroud)
那不是团队合作者,他将修复你介绍的错误.你应该怎么做?
鉴于我有一个基于CharFieldor CharField的模型字段的遗留模型,如:
class MyModel(models.Model):
name = models.CharField(max_length=1024, ...)
...
Run Code Online (Sandbox Code Playgroud)
我需要进行迁移以使其具有max_length最大值.255.首先,我正在编写一个datamigration使任何超过255个字符的值适应即将到来schemamigration的修复列的最大长度,我将在此工作后立即执行.
问题是我有一个非常大的数据集,我知道并非所有行都包含超过255个字符的值MyModel.name,我想考虑我的迁移只有那些人.
是否有任何方法(使用)django ORM仅过滤满足此条件的对象?就像是:
MyModel.objects.filter(name__len__gte=255)
Run Code Online (Sandbox Code Playgroud)
会很棒,但我相信这是不可能的,或者至少它不是那么简单.
有人知道完成此查询的任何方法吗?
谢谢!
我有一个模型,我设法在两台不同的计算机上迁移没有问题.但是在我的服务器上我收到以下错误:
迁移错误:some_app:0002_auto__some_migration
AttributeError:'DatabaseOperations'对象没有属性'shorten_name'
检查迁移文件我看到一行:
m2m_table_name = db.shorten_name(u'some_app_some_class_some_attribute')
Run Code Online (Sandbox Code Playgroud)
这可能是罪魁祸首.(有几行使用它shorten_name.我不知道如何解决这个问题.
我的服务器上的虚拟环境有南0.7.6,Django 1.5(以及Postgis启用的postgres)
我有一个Realm Object建模如此
class WorkoutSet: Object {
// Schema 0
dynamic var exerciseName: String = ""
dynamic var reps: Int = 0
// Schema 0 + 1
dynamic var setCount: Int = 0
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试执行迁移.
在我的AppDelegate导入内RealmSwift.
在didFinishLaunchWithOptions我调用的函数内
Migrations().checkSchema()
Run Code Online (Sandbox Code Playgroud)
迁移是在另一个文件中声明的类.
在该文件中有一个声明为这样的结构.
func checkSchema() {
Realm.Configuration(
// Set the new schema version. This must be greater than the previously used
// version (if you've never set a schema version before, the version is 0).
schemaVersion: 1, …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用db/seed.rb文件和rake db:seed命令将一些数据植入我正在开发的Rails 3应用程序中.
我正在播种的数据涉及一个名为Meeting的数据库表,该表有三列:字符串标题,日期时间startDate,datetime endDate.我试图插入的日期时间是"mm/dd/yyyy hh:mm"格式 - 例如."01/02/2003 13:23"= 2003年1月2日下午1:23.但是,DateTime.parse()始终错误地显示"无效日期"错误 - 因为它尝试以"dd/mm/yyyy"格式解析日期.
从我的谷歌搜索,我被引导相信,在解析DateTime对象时,编译器会查看传入的字符串并进行一些仓促的模式匹配,然后相应地映射"mm/dd/yyyy"和"dd-mm-yyyy"根据是否使用斜线或破折号作为分隔符的美国/英国(等)标准.然而,情况似乎并非如此,我想知道为什么.以及如何解决它.
这就是我为会议播种的方式 - 第一个正确解析,第二个失败.
Meeting.create([
{
:title => "This meeting parses fine",
:startDate => DateTime.parse("09/01/2009 17:00"),
:endDate => DateTime.parse("09/01/2009 19:00")
},
{
:title => "This meeting errors out",
:startDate => DateTime.parse("09/14/2009 8:00")
:endDate => DateTime.parse("09/14/2009 9:00")
}])
Run Code Online (Sandbox Code Playgroud) 我一直在尝试使用MVC 3的EF 4.1(代码优先).我正在考虑应用程序何时需要更改.我测试了几个场景.我喜欢在模型(我的POCO)发生变化时手动编辑数据库的想法.
更改模型时出现ASP.NET错误:
"自创建数据库以来,支持'CTCMContext'上下文的模型已经发生了变化.手动删除/更新数据库......"
现在,它说我可以" 手动更新数据库 ",但我做了,仍然得到相同的错误.我错过了什么!!?!
编辑
这与EF生成的模型哈希有关吗?
migration data-migration entity-framework ef-code-first entity-framework-4.1
在架构更改后,我必须在Postgres DB中迁移大量现有数据.
在旧模式中,country属性将存储在users表中.现在,country属性已移至单独的地址表中:
users:
country # OLD
address_id # NEW [1:1 relation]
addresses:
id
country
Run Code Online (Sandbox Code Playgroud)
模式实际上更复杂,地址不仅包含国家/地区.因此,每个用户都需要拥有自己的地址(1:1关系).
迁移数据时,我在插入地址后在users表中设置外键时遇到问题:
INSERT INTO addresses (country)
SELECT country FROM users WHERE address_id IS NULL
RETURNING id;
Run Code Online (Sandbox Code Playgroud)
如何传播插入行的ID并在users表中设置外键引用?
到目前为止,我能想出的唯一解决方案是在地址表中创建一个临时的user_id列,然后更新address_id:
UPDATE users SET address_id = a.id FROM addresses AS a
WHERE users.id = a.user_id;
Run Code Online (Sandbox Code Playgroud)
然而,事实证明这非常慢(尽管在users.id和addresses.user_id上都使用了索引).
users表包含大约300万行,其中300k缺少相关地址.
有没有其他方法可以将派生数据插入到一个表中,并在另一个表中设置插入数据的外键引用(不更改架构本身)?
我正在使用Postgres 8.3.14.
谢谢
我现在通过使用Python/sqlalchemy脚本迁移数据来解决问题.事实证明(对我来说)比用SQL尝试更容易.不过,如果有人知道在Postgres SQL中处理INSERT语句的RETURNING结果的方法,我会感兴趣.
我从我的ubuntu安装了alembic 0.3.4,sqlalchemy,SQLite版本3.7.4,并将SQLAlchemy 0.6.4升级到SQLAlchemy 0.7或更高版本.我按照说明操作:http://alembic.readthedocs.org/en/latest/tutorial.html
现在我正在测试:自动生成迁移我创建了一个包:schemas和一个包标记下的模式:init .py,其中定义了一行:
__all__ = ["teacher"]
Run Code Online (Sandbox Code Playgroud)
我还在schemas目录中创建了一个模块文件:dbmodel.py,其中包含以下内容
Base = declarative_base()
class teacher(Base):
__tablename__ = 'teacher'
id = Column(Integer, primary_key=True)
name = Column(String)
department = Column(String)
Run Code Online (Sandbox Code Playgroud)
顺便说一下,我创建了一个sqlite数据库,并且在自动生成迁移之前进行一些测试它运行正常.我配置了env.py文件.添加了两行:
from schemas.dbmodel import Base
target_metadata = Base.metadata
Run Code Online (Sandbox Code Playgroud)
然后我跑:
alembic revision --autogenerate -m "Added teacher table"
Run Code Online (Sandbox Code Playgroud)
但仍然得到错误:
Traceback (most recent call last):
File "/usr/local/bin/alembic", line 9, in <module>
load_entry_point('alembic==0.3.4', 'console_scripts', 'alembic')()
File "/usr/local/lib/python2.7/dist-packages/alembic-0.3.4-py2.7.egg/alembic/config.py", line 229, in main
**dict((k, getattr(options, k)) for k in kwarg)
File "/usr/local/lib/python2.7/dist-packages/alembic-0.3.4-py2.7.egg/alembic/command.py", line 93, …Run Code Online (Sandbox Code Playgroud) 我有一个运行带有主机数据量的mysql-5.5的docker容器.我正在将我的容器升级到mysql-5.6.我正在启动一个具有相同主机卷的新容器.由于mysql.user表崩溃,MySQL在容器中崩溃.
[ERROR] Fatal error: Can't open and lock privilege tables:
Incorrect key file for table 'user'; try to repair it
160523 12:04:13 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
Run Code Online (Sandbox Code Playgroud)
我尝试了以下方法来解决这个问题:
root@container# mysqld --skip-grant-tables;
root@container# mysql -uroot -ppassword
mysql> repair table user USE_FRM;
+------------+--------+----------+--------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+------------+--------+----------+--------------------------------------------------+
| mysql.user | repair | info | Key 1 - Found wrong stored record at 0 |
| mysql.user | repair | info | Found …Run Code Online (Sandbox Code Playgroud) 我使用Django 1.7迁移,特别是想要用初始数据填充新创建的数据库.因此,我使用数据迁移.它看起来像这样:
def populate_with_initial_data(apps, schema_editor):
User = apps.get_model("auth", "User")
new_user = User.objects.create(username="nobody")
class Migration(migrations.Migration):
...
operations = [
migrations.RunPython(populate_with_initial_data),
]
Run Code Online (Sandbox Code Playgroud)
同时,我希望UserDetails每个新用户都有一个模型实例:
@receiver(signals.post_save, sender=django.contrib.auth.models.User)
def add_user_details(sender, instance, created, **kwargs):
if created:
my_app.UserDetails.objects.create(user=instance)
Run Code Online (Sandbox Code Playgroud)
但是:此信号仅在迁移之外有效.原因是,apps.get_model("auth", "User")与django.contrib.auth.models.User没有发送信号的情况完全不同.如果我尝试手动执行此操作,则会失败:
signals.post_save.send(django.contrib.auth.models.User, instance=julia, created=True)
Run Code Online (Sandbox Code Playgroud)
这失败了,因为那时,信号处理程序尝试使用O2O 创建一个新的 UserDetails指向历史记录 User:
ValueError: Cannot assign "<User: User object>": "UserDetails.user" must be a "User" instance.
Run Code Online (Sandbox Code Playgroud)
游民.
好的,我可以直接调用信号处理程序.但是我必须UserDetails在关键字参数(以及它需要的其他历史类)中传递历史类.此外,UserDetails具有此数据迁移的应用程序不是具有此数据迁移的应用程序,因此这将是一个丑陋的依赖性,很容易破坏,例如,如果UserDetails应用程序被删除INSTALLED_APPS.
那么,这只是一个当前的限制,我必须解决丑陋的代码和FixMe评论?或者有没有办法从数据迁移中发送信号?
data-migration ×10
django ×3
django-south ×2
migration ×2
postgresql ×2
python ×2
ruby ×2
alembic ×1
docker ×1
mysql ×1
mysql-5.6 ×1
orm ×1
realm ×1
sql ×1
sqlalchemy ×1
swift ×1