我正在使用Jeremy Evan的Sequel来填充(SQLite)数据库,其中包含我从网页中搜集的数据。 数据库涉及我用Associations表达的许多多对多关系。 关联是在类定义中创建的,在运行脚本时始终会对其进行评估。 重要的是,关联类定义需要具有必要的表。 因此,表创建方法应该在关联定义的顶层。 这是一个例子:
module Thing
db = Sequel.Sqlite('data.sqlite')
db.create_table(:clients)
String :client_id, :primary_key => true
String :client_data
end
db.create_table(:orders)
String :order_id, :primary_key => true
String :order_data
end
db.create_table(:orders_clients)
String :order_id
String :client_id
primary_key [:order_id,:client_id]
end
class Person < Sequel::Model
unrestrict_primary_key
many_to_many :orders
end
class Order < Sequel::Model
unrestrict_primary_key
many_to_many :orders
end
end
首先,我认为这是一个相当脏的解决方案,因为我的方法调用和类定义位于同一个命名空间中。
如果我尝试分离类定义,我会得到No database associated with Sequel::Model
错误(这是有道理的,但我想推迟对关联定义的评估,在表调用之后,只要它们可能发生)。
我希望能够在方法调用中创建表和关联。因此,我可以传递新数据库文件的名称:
def create_tables_and_schema (database_name)
db = Sequel.Sqlite(database_name)
db.create_table... #three of those, as above
class Person < Sequel::Model
unrestrict_primary_key
many_to_many :orders
end
class Order < Sequel::Model
unrestrict_primary_key
many_to_many :orders
end
end
我认为需要的是表达表关系的另一种方式。
对方法和风格的任何建议都表示赞赏。如果解释令人困惑,请询问澄清。
答案 0 :(得分:5)
您的方法调用和类定义不需要位于同一名称空间中,只需要在模型类之前创建表。分离它们的一种简单方法是将表创建移动到单独的文件中。此外,通常将数据库对象分配给常量。
create_tables.rb:
DB.create_table(:clients)
String :client_id, :primary_key => true
String :client_data
end
DB.create_table(:orders)
String :order_id, :primary_key => true
String :order_data
end
DB.create_table(:orders_clients)
String :order_id
String :client_id
primary_key [:order_id,:client_id]
end
models.rb:
DB = Sequel.sqlite('data.sqlite')
require 'create_tables'
class Person < Sequel::Model
unrestrict_primary_key
many_to_many :orders
end
class Order < Sequel::Model
unrestrict_primary_key
many_to_many :orders
end
您提到要在方法调用中创建表和关联,但如果要创建具有常量的类则没有意义。通过方法调用创建它们的主要原因是在运行时允许多个数据库,但这不适用于您的模型类,因为它们是使用常量名称定义的。
如果在运行时不需要多个数据库,如果您只想将表创建与模型创建分开,上面的示例应该有效。
如果在运行时确实需要多个数据库,那么通过方法调用创建表和模型是有意义的,但是您需要创建匿名模型类,否则您将遇到问题。