我正在寻找一个Ruby ORM来取代ActiveRecord.我一直在看Sequel和DataMapper.它们看起来很不错,但是它们似乎都不是基本的:当你不需要时,不要将所有内容都加载到内存中.
我的意思是我在ActiveRecord和Sequel上尝试了以下(或等效的)有很多行的表:
posts.each { |p| puts p }
Run Code Online (Sandbox Code Playgroud)
他们两个都记忆犹新.它们似乎将所有内容加载到内存中,而不是在需要时获取内容.我find_in_batches在ActiveRecord中使用了它,但这不是一个可接受的解决方案:
为什么我的代码应该知道分页机制?我很高兴配置页面大小的某个地方,但就是这样.有了find_in_batches你需要做的是这样的:
post.find_in_batches {| batch | batch.each {| p | 把p}}
但这应该是透明的.
那么有可靠的Ruby ORM可以正确获取吗?
更新:
正如塞尔吉奥所说,在Rails 3中你可以使用find_each我想要的东西.但是,由于ActiveRecord不是一个选项,除非有人能说服我使用它,所以问题是:
find_each,而find应该这样做,不应该吗?好吧,我一直试图找出数据映射器和存储库之间的区别,但到目前为止我还没有.在我看来,专家程序员说"存储库是查询构造代码集中的映射层的另一个抽象层".这似乎可以理解,但仍然有点抽象.我之前读过stackoverflow上的这篇文章,它让我更加困惑: Data Mapper模式与存储库模式有何不同?
我想我需要的是关于两种模式如何不同的简单解释和具体/实际示例,以及数据映射器不具备的存储库,反之亦然.你们中的任何人都知道一个关于说明数据映射器和存储库概念的好例子吗?如果它是相同的示例,只有一个使用数据映射器而另一个使用存储库会更好.谢谢,我非常感谢.到目前为止我仍然很困惑......
我正在使用DataMapper在Sinatra上创建一个简单的应用程序.我希望看到为我的各种链式查找器创建DM的查询等.
我试过了:
DataMapper::Logger.new(STDOUT, :debug)
Run Code Online (Sandbox Code Playgroud)
在我的configure do ... end块中environment.rb,在应用程序启动时加载的文件中.
我也尝试过:
DataMapper::Logger.new('log/my-app.log', :debug)
Run Code Online (Sandbox Code Playgroud)
无论是通过浏览器还是通过irb需要我的应用程序的会话,都可以从应用程序中获取日志语句.我看到应用程序启动消息.
我正在使用rackup config.ru本地运行应用程序.
我错过了什么?
这个问题在清除我对此事的困惑方面做得非常好,但我很难找到关于服务层的确切限制应该是什么的可靠来源.
对于这个例子,假设我们正在处理书籍,我们希望通过作者获得书籍.本BookDataMapper可以有一个通用的get()接受条件(S),如书的唯一标识符,作者姓名等这个实现是相当微不足道的(逻辑)方法,但如果我们希望有需要更复杂的查询多个条件是什么?
让我们说我们希望得到某位作者在特定出版商下撰写的所有书籍.我们可以扩展BookDataMapper->get()方法来解析多个条件,或者我们可以编写一个新的方法,如BookDataMapper->getByAuthorAndPublisher().
是否最好让服务层直接调用这些[更具体]的方法,或者在调用BookDataMapper->get()多个条件传递的更通用方法之前解析条件?在后一种情况下,服务层将执行更多逻辑"繁重的工作",使数据映射器相当简单.前一个选项会将服务层几乎完全缩减为中间人,将条件逻辑留给数据映射器等方法BookDataMapper->getByAuthorAndPublisher().
让服务层解析条件的一个明显问题是某些域逻辑泄漏出数据映射器.(这在此处的链接问题中进行了解释.但是,如果服务层要处理条件,则逻辑不会使其脱离模型层;控制器将无论如何调用$book_service->getByAuthorAndPublisher().
我想定义我的自定义序列化策略(包括哪些字段),同时使用Jackson.我知道,我可以使用视图/过滤器来完成它,但它引入了非常糟糕的事情 - 使用字段名称的字符串表示,这会自动启用自动重构的问题.
如何强制杰克逊仅序列化带注释的属性,仅此而已?
我有Spork测试服务器的问题.
如果我在config/environments/test.rb中设置config.cache_classes = false,那么规范就会开始出现rasie错误.
Failure/Error: task = Factory(:something, :foo => @foo, :bar => @bar)
DataMapper::ImmutableError:
Immutable resource cannot be modified
Run Code Online (Sandbox Code Playgroud)
这是我的spec_helper.rb:
require 'spork'
Spork.prefork do
if ENV['CODE_COVERAGE'] == '1'
require 'simplecov'
SimpleCov.start 'rails'
end
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'webmock/rspec'
require 'factory_girl'
Dir[Rails.root.join("spec/controllers/shared/*.rb")].each { |f| require f }
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
RSpec.configure do |config|
config.mock_with :mocha
config.include Rails.application.routes.url_helpers
config.include UrlHelper
config.before(:each) do
repository(:default) do
transaction = DataMapper::Transaction.new(repository)
transaction.begin
repository.adapter.push_transaction(transaction)
end
end
config.after(:each) do …Run Code Online (Sandbox Code Playgroud) 从DataMapper文档中,我认为至少需要调用四个函数才能进行数据库设置:
DataMapper.setup(:default, 'sqlite:///path/to/project.db')
DataMapper.finalize
DataMapper.auto_migrate!
DataMapper.auto_upgrade!
Run Code Online (Sandbox Code Playgroud)
在许多DataMapper + Sinatra教程中,我了解到auto_migrate!并且auto_upgrade!不应该在每次在生产服务器上加载应用程序时调用它.但同时许多例子在sinatra应用程序的主ruby文件中调用这些函数,比如说app.rb,没有额外的检查.而一些例子根本不打电话finalize.到目前为止,我很困惑,我不知道在生产服务器上做什么.
以下是简单app.rb的例子,我有一些问题:
finalize被召集?db,生产服务器上没有文件,如何自动创建它?或者我必须project.db手动创建文件?auto_upgrade!被包装在:development块中,因此不会在生产服务器上调用它.当我在其中添加或删除列时,我应该如何升级数据库?require 'sinatra'
require 'data_mapper'
configure do
DataMapper.setup :default, "sqlite3://#{Dir.pwd}/project.db"
end
class Book
include DataMapper::Resource
property :id, Serial
property :title, Text
belongs_to :author
end
class Author
include DataMapper::Resource
property :id, Serial
property :name, Text
has n, :books
end
configure :development do
DataMapper.auto_upgrade!
end
get '/:id' do …Run Code Online (Sandbox Code Playgroud) 我遇到了几个最近宣布他们计划将他们的实现从Active Record转移到Data Mapper的ORM.我对这个主题的了解非常有限.对于那些了解得更好的人来说,问题是Data Mapper比Active Record更新吗?当Active Record运动开始时它是否存在?两者如何联系在一起?
最后,由于我不是一个数据库人,对这个主题知之甚少,我是否应该遵循正在转向Data Mapper实现的ORM,就像我作为编写软件的人(不是数据人)的内容一样?
我最近开始研究Flask和Flask-SQLAlchemy.来自Django背景我发现Flask-SQLAlchmey非常复杂.我已经读过,SQLAlchemy实现了Data Mapper模式,而Django ORM则基于Active Record Pattern.
下面是一个编写的示例代码,它实现了访问数据库的存储库模式.
这是S.Lott(271k声誉)评论的另一个链接,他说ORM是数据访问层,它与模型分开.
我的问题是这些:
Question.query.filter_by(text = text).all()不比使用更好
db.session.query(Question).filter(Question.text == text).all()?这不是DataMapper与ActiveRecord模式的重复,因为这只是告诉定义,我对实际例子更感兴趣.
python activerecord design-patterns datamapper flask-sqlalchemy
我正在阅读POEAA的架构模式章节,Fowler说"随着域逻辑变得越来越复杂,你开始转向丰富的域模型(116),Active Record(160)的简单方法开始崩溃当你将域逻辑分解为较小的类时,域类与表的一对一匹配开始失败.关系数据库不处理继承,因此很难使用策略[Gang of Four]和其他简洁的OO模式随着域逻辑变得越来越强大,你希望能够在不必经常与数据库通信的情况下对其进行测试."
我真的不明白这一点.通过"域类与表的一对一匹配",他是否仅表示没有关联或单表继承层次结构的类?
为什么将域逻辑分解为较小的类会导致模式失败?
datamapper ×10
orm ×3
ruby ×3
activerecord ×2
php ×2
sinatra ×2
database ×1
domain-model ×1
factory-bot ×1
jackson ×1
java ×1
json ×1
mysql ×1
poeaa ×1
python ×1
repository ×1
rspec ×1
sequel ×1
spork ×1
sqlite ×1