在C#/ .Net世界中,有一些ORM,如NHibernate或ActiveRecord,包括透明缓存:数据库更新透明地复制到缓存,对象在可用时直接从缓存中检索等(通常使用memcached).
在带有DBIx :: Class的 Perl中,它看起来不像透明缓存.我错过了什么?这似乎是一个普遍的需求,我很惊讶我在CPAN或谷歌上找不到任何东西.
我想弄清楚我的CGI :: Application中的哪个模块正在加载Moose.我试图超载"require"但我似乎没有正确的语法.如果有人可以清理以下代码,我将不胜感激:
use strict;
use warnings;
use Carp qw//;
BEGIN {
*CORE::GLOBAL::require = sub (*) {
warn "Requiring $_[0] at: " . Carp::longmess();
CORE::require (@_);
};
}
Run Code Online (Sandbox Code Playgroud)
基本上,这个脚本的问题是它实际上并没有加载任何东西.当CORE :: require(@ )被调用时,它不会"做"任何事情.我尝试直接使用$ [0] 传递脚本名称,但这只会导致脚本死锁,直到它超时.
注意:上面的脚本位于我的启动脚本的开头
我们有一个链接表,可以在一侧处理多种类型的对象,我无法弄清楚如何使用has_many从这些对象之一到链接表.
示例:链接表包含:
Run Code Online (Sandbox Code Playgroud)id link_id link_table resource_id 1 1 page 3 2 1 page 5 3 2 page 3 4 1 not_page 1
从资源方面建立关系很容易:
Resource->has_many(links => 'Link', 'resource_id');
Run Code Online (Sandbox Code Playgroud)
但我无法从页面方面获得相应的关系:
Page->has_many(links => 'Link', 'link_id');
Run Code Online (Sandbox Code Playgroud)
会得到not_page链接
Page->has_many(links => 'Link', {'foreign.link_id' => 'self.id', 'foreign.link_table' => 'page'});
Run Code Online (Sandbox Code Playgroud)
给出了"无效的rel cond val页面"错误(这对我来说并不奇怪).
Page->has_many(links => 'Link', {'foreign.link_id' => 'self.id', 'foreign.link_table' => '"page"'});
Run Code Online (Sandbox Code Playgroud)
给出"无效的相关信息"页面"'错误.投掷反斜杠并没有帮助.
DBIx :: Class :: Relationship :: Base说:
条件必须是表之间连接的SQL :: Abstract风格表示
我从那里尝试了各种不同的选择,例如:
Page->has_many(links => 'Link', {'foreign.link_id' => 'self.id', 'foreign.link_table' => {'=', 'page'}});
Run Code Online (Sandbox Code Playgroud)
但没有任何成功. …
假设我有一个由三个表组成的以下简化示例数据库:
CREATE TABLE people (
person_id INTEGER PRIMARY KEY,
person_name VARCHAR(100)
);
CREATE TABLE events (
event_id INTEGER PRIMARY KEY,
event_name VARCHAR(100),
event_creator INTEGER
CONSTRAINT fk_event_creator REFERENCES people(person_id)
);
CREATE TABLE event_attendees (
event_id INTEGER NOT NULL
CONSTRAINT fk_event_attendee_event
REFERENCES events(event_id),
person_id INTEGER NOT NULL
CONSTRAINT fk_event_attendee_person
REFERENCES people(person_id),
role CHAR(1), -- O: organizer, P: performer, S: speaker, G: guest
CONSTRAINT pk_event_attendees PRIMARY KEY (event_id, person_id)
);
Run Code Online (Sandbox Code Playgroud)
给定一个event_id,我可能想要查询所有组织者的名字,考虑到person_id我可能想要找到这个人是该事件的客人或创建者的所有事件的名称,依此类推.
我知道如何使用简单的SQL做所有这些.你能告诉我在设置DBIx :: Class时需要设置哪些结果类以及需要指定哪种关系?
我目前正在尝试使用DBIx实现以下方案:
表产品包含"一般产品"和"捆绑产品"(捆绑产品是一般产品的集合):
package Product;
use base 'DBIx::Class::Core';
__PACKAGE__->table("products");
__PACKAGE__->add_columns(
"productId",
{ data_type => "varchar", is_nullable => 0, size => 10},
"name",
{ data_type => "varchar", is_nullable => 1, size => 150},
"type",
{
data_type => "enum",
default_value => "general",
extra => {
list => ["general", "bundle"],
},
is_nullable => 0,
});
Run Code Online (Sandbox Code Playgroud)
如您所见,产品是一般产品,或捆绑产品保存在色谱柱类型中.
现在我想将这些信息封装在类标识中:我想要以下类:
type无所谓)type='bundle')type='general')我写:
package BundleProduct;
use base 'Product';
__PACKAGE__->resultset_attributes({ where => { …Run Code Online (Sandbox Code Playgroud) 由于历史原因,我们有一个工作表,在文本字段中具有与另一个表中的ID对应的整数值.例:
CREATE TABLE things (
id INTEGER,
name VARCHAR,
thingy VARCHAR
);
CREATE TABLE other_things (
id INTEGER,
name VARCHAR,
);
Run Code Online (Sandbox Code Playgroud)
所以"东西"有一个"其他东西",但是不是合理地设置,连接字段是varchar,并且称为"thingy".
所以在Postgres中,我可以这样做来加入这两个表:
SELECT t.id, t.name, ot.name FROM things t
JOIN other_things ot ON CAST(t.thingy AS int) = ot.id
Run Code Online (Sandbox Code Playgroud)
我怎样才能在DBIx :: Class中表示这种关系?这是我尝试过的一件事的例子:
package MySchema::Thing;
__PACKAGE__->has_one(
'other_thing',
'MySchema::OtherThing',
{ 'foreign.id' => 'CAST(self.thingy AS int)' },
);
Run Code Online (Sandbox Code Playgroud) 我发现很难找到有关如何使用组装DBIx::Class模式结构的信息Moose.如何正确地(基本上工作)和现代Perl(良好的风格,快速,没有警告)?
这些是我的目标:
Moose::Manual::BestPractices,特别是:
namespace::autoclean和__PACKAGE__->meta->make_immutable.Result和ResultSetsub BUILDARGS { $_[2] }解释不要问)MooseX::NonMoose(如果需要)或者__PACKAGE__->load_components按照建议移动到公共基类中DBIx::Class::Manual::Cookbook这些是我遇到的问题:
__PACKAGE__->meta->make_immutable我得到了类似的警告Not inlining 'new' for MyApp::Schema::Result::MyTable since it is not inheriting the default Moose::Object::new__PACKAGE__->load_components到Result基类时,我的datetime列没有被夸大使用DBIx :: Class,我有一个结果集,需要通过SQL无法生成的数据进行过滤.我需要做的是有效地等同于这个假设的例子:
my $resultset = $schema->resultset('Service')->search(\%search);
my $new_resultset = $resultset->filter( sub {
my $web_service = shift;
return $web_service->is_available;
} );
Run Code Online (Sandbox Code Playgroud)
阅读文档让我不知道如何完成这样的策略.
我想从表中检索行,DBIx::Class并从同一个表中预取相应的行,其中列具有特定的其他值.我需要从计划A中获取所有作业(复制它们)并从计划B中检索所有相应的作业.
我已经编制了测试表,看起来像这样:
CREATE TABLE tasks (
id INTEGER
);
CREATE TABLE schedules (
id INTEGER
);
CREATE TABLE assignments (
id INTEGER,
scheduleId INTEGER,
taskId INTEGER,
worker TEXT,
FOREIGN KEY (scheduleId) REFERENCES schedules(id),
FOREIGN KEY (taskId) REFERENCES tasks(id)
);
Run Code Online (Sandbox Code Playgroud)
计划1有一些任务,计划2有一些任务:
INSERT INTO tasks (id) VALUES (1);
INSERT INTO tasks (id) VALUES (2);
INSERT INTO schedules (id) VALUES (1);
INSERT INTO schedules (id) VALUES (2);
INSERT INTO assignments (id,scheduleId,taskId,worker) VALUES (1,1,1,"Alice");
INSERT INTO assignments (id,scheduleId,taskId,worker) VALUES (2,1,2,"Bob");
INSERT INTO …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用DBIx:Class.我已经使用DBIx:class :: Schema :: Loader成功创建了Schema类.
我也可以连接到数据库.
#!/usr/bin/perl -w
use Test::More tests => 5;
use_ok('Models::ModelRole');
use_ok('Models::User');
my $model = Models::User->new();
cmp_ok($model->{ModelName}, 'eq', 'User', 'model name');
ok($model->connect(), "connect"); #works
ok($model->{schema}->resultset('User'));
Run Code Online (Sandbox Code Playgroud)
最后一个测试返回错误消息:
DBIx::Class::Schema::source(): Can't find source for User at ./tests/ModelsTests.pl line 29
Run Code Online (Sandbox Code Playgroud)
这是DBIx生成的类的结构:Class :: Schema :: Loader:

这是模型用户类:
package Models::User;
use DB::Glued::Schema::Result::User;
use Models::ModelRole;
use Moose;
with 'Models::ModelRole';
sub BUILD {
my $self = shift;
$self->{schema} = Glued::Schema::Result::User->new();
my @name = split('::', __PACKAGE__);
$self->{ModelName} = $name[-1];
}
1;
Run Code Online (Sandbox Code Playgroud)
我希望这是足够的信息.
dbix-class ×10
perl ×10
moose ×2
base ×1
caching ×1
inheritance ×1
isa ×1
join ×1
orm ×1
postgresql ×1
sql ×1