正在将 MongoDB 迁移到 postgres。
感谢 postgres JSON ,这使得将嵌套文档作为 JSON 移动变得容易。但问题始于迁移“ID”字段。
Mongo 生成一个大的十六进制数 56c4100560b2d8308f4bde21
我尝试将其转换为 BigInt,不幸的是它超出了范围 26397231623443762880753094891
ID 无法重新生成,因为它在各处的文档之间相互链接。
字符串不能用作 ID 字段,因为我正在迁移到 Postgres + JPA,并且我将使用自动生成序列。
有什么办法,我可以将这个十六进制缩短为更短版本的 Int 或 BigInt ,同时我应该保持唯一性
我尝试取模,但它带来了重复
最佳答案
您最好的选择是迁移 MongoDB 的 ObjectId字段到 PostgreSQL 的 uuid 列。请注意,UUID 中有更多字节,因此您需要填充这些值。
查看更多信息:
如果你真的想用bigint s,你有两个选择:
<强>1。创造全新的值(value)
text/varchar为你的ObjectId值(value)观(目前)ON UPDATE CASCADE对于所有 ObjectId专栏。ObjectId 的表专栏。更新 ObjectId列(虽然它们仍然是 text/varchar ),其中:
UPDATE table_name
SET object_id_col = nextval('table_name_object_id_col_seq')::text
(这会将更改传播到引用表,因为外键是较早设置的。)
ObjectId 的列类型列到 bigint OWNED BY表格列nextval('table_name_object_id_col_seq')作为默认值此方法保证在迁移过程中永远不会出现重复值。该序列可用于为主键创建新值。
<强>2。以某种方式使用您的原始值
截断会导致信息丢失,因此无论您尝试什么方法,您可能都会得到重复的值。但是,您可以使用 f.ex 来减少这种情况的发生。按位XOR (通常是 PostgreSQL 中的 # 运算符)而不是模数。
有了这个函数 f.ex。您可以将原始值用作:
0 (或与其他人一起,固定起始值)<the_previous_result> # <value_from_2.> 这是一个执行此操作的 SQL 函数:
create or replace function hex_xor(p_hex text, p_bits int default 64, p_default bigint default 0)
returns bigint
language sql
immutable
as $func$
with recursive r as (
select ('x' || p_hex)::varbit h, p_default r, 0 i
union all
select case
when bit_length(h) <= p_bits then varbit ''
else substring(h for bit_length(h) - p_bits)
end,
r # case
when bit_length(h) <= p_bits then h::bit(64)::bigint
else substring(h from bit_length(h) - p_bits + 1 for p_bits)::bigint
end,
i + 1
from r
where bit_length(h) > 0
)
select r
from r
order by i desc
limit 1
$func$;
这假设 p_hex参数实际上是十六进制格式 & p_bits参数永远不会大于 64 .
但是如果你只是按原样使用它,你可能会在稍后结束,在 INSERT 上有冲突的值.你能做的就是f.ex。使用:
select -hex_xor('56c4100560b2d8308f4bde21', 63)
迁移时。这样迁移了ObjectId s 将始终为负值 & 稍后生成的主键(f.ex. 来自序列)将始终为正值。
关于mongodb - Mongo 到 Postgres 迁移 - 将 mongo hexa Id 字段转换为更短的整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43039653/
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr