将DBIC_TRACE环境变量设置为true:
BEGIN { $ENV{DBIC_TRACE} = 1 }
Run Code Online (Sandbox Code Playgroud)
生成非常有用的输出,特别是显示正在执行的SQL查询,但SQL查询全部在一行上.
有没有办法推动它通过一些有点"sql整洁"的例程来更好地格式化它,或许可以在多行中分解它?如果不这样做,任何人都可以给我一个推动代码中我需要破解添加这样一个钩子的地方吗?最好的工具是接受格式错误的SQL查询并推出格式良好的SQL查询?
在这种情况下,"良好的格式化"仅仅意味着比"一条线上的所有"更好.我并不特别关注格式化查询的特定样式
谢谢!
我有一张成对的物品表.我想自己加入它,这样我就可以在一个查询中检索该对的两侧.它是有效的SQL(我认为),SQLite引擎实际上接受它,但我无法让DBIx :: Class咬紧牙关.
package Schema::Half;
use parent 'DBIx::Class';
__PACKAGE__->load_components('Core');
__PACKAGE__->table('half');
__PACKAGE__->add_columns(
whole_id => { data_type => 'INTEGER' },
half_id => { data_type => 'CHAR' },
data => { data_type => 'TEXT' },
);
__PACKAGE__->has_one(dual => 'Schema::Half', {
'foreign.whole_id' => 'self.whole_id',
'foreign.half_id' => 'self.half_id',
# previous line results in a '='
# I'd like a '<>'
});
package Schema;
use parent 'DBIx::Class::Schema';
__PACKAGE__->register_class( 'Half', 'Schema::Half' );
package main;
unlink 'join.db';
my $s = Schema->connect('dbi:SQLite:join.db');
$s->deploy;
my $h = $s->resultset('Half'); …Run Code Online (Sandbox Code Playgroud) 给定DBIx :: Class结果集,例如:
my $rs = $c->model("DB::Card")->search({family_name => "Smith"});
Run Code Online (Sandbox Code Playgroud)
我读过的教程使用stash传递一行arrayref:
$c->stash->{cards} = [$rs->all];
Run Code Online (Sandbox Code Playgroud)
这导致查询在此时执行,并且生成的对象填充到存储中,因此它们可以在TemplateToolkit中用作:
[% FOREACH card IN cards %]
[% card.given_name %] [% card.family_name %]
[%END%]
Run Code Online (Sandbox Code Playgroud)
有没有一种正确的方法让TT在从数据库中获取时对行进行迭代?
在Perl链接方法中处理异常的最佳方法是什么?如果链接的任何方法抛出异常,我想分配值0或undef
代码示例:
my $x = $obj->get_obj->get_other_obj->get_another_obj->do_something;
Run Code Online (Sandbox Code Playgroud)
最好的办法是什么?我每次都必须在try/catch/finally语句中包装吗?我想要应用的上下文是:我正在使用Catalyst和DBIC进行Web开发,我做了很多链式结果集,如果这个结果集中的一些抛出异常,我只想分配0或undef的值,然后对待它模板中的错误(我使用Template Toolkit).如果还有另一种方法可以做到这一点而不包含try/catch中的每个调用,请告诉我.如果您知道在相同的上下文(Catalyst/DBIC/TT)中处理此类错误的更好方法,请建议.一个实际的例子是当用户搜索某些内容时,这不存在.
对于任何给定的结果类MySchema :: Result :: Foo(从默认模式加载器生成的语法构建,使用Moose/MooseX :: nonmoose)
如果我添加一个BUILDARGS方法包装来清理行的构造函数数据,如下所示:
package MySchema::Result::Foo;
use Moose;
use MooseX::NonMoose;
[etc ..]
around 'BUILDARGS' => sub {
my $orig = shift;
my $class = shift;
delete $_[0]->{not_a_real_column};
return $class->$orig(@_);
};
Run Code Online (Sandbox Code Playgroud)
它直接使用架构时有效.例如,以下按预期工作:创建一个新的行对象,使用real_column =>'value'并删除not_a_real_column - > new
use MySchema;
my $s = MySchema->connect('dbi:blahblahblah');
$s->resultset('Foo')->new({ real_column=>'value', not_a_real_column=>'some other thing' }); #win
Run Code Online (Sandbox Code Playgroud)
但是,当通过Catalyst :: Model :: DBIC :: Schema使用相同的模式时,顺序是不同的.尝试创建新的Foo行对象时,以下操作失败,因为not_a_real_column无效.换句话说,在调用new之前,new的参数不会通过BUILDARGS运行.
$c->model('MySchemaModel')->resultset('Foo')->new({ real_column=>'value', not_a_real_column=>'some other thing' }); #fails
Run Code Online (Sandbox Code Playgroud)
有趣的是,如果我绕过'new'=> sub {}而不是'BUILDARGS'=> sub {},两种情况下的行为是相同的,并且工作正常,但据我所知,Moose教条声明永远不会弄乱新.
任何人都在关心帮助我理解为什么会这样,或者是否有更好的方法?
除了使用视图和手动编写SQL之外,我还没有找到与DBIx :: Class进行联合的方法.这对我来说很奇怪.我觉得应该有一些方法来结合两个ResultSet而不需要额外的工作,因为set加法和减法是SQL的核心部分.有没有更简单的工会方式?如果没有,为什么不呢?
在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] 传递脚本名称,但这只会导致脚本死锁,直到它超时.
注意:上面的脚本位于我的启动脚本的开头
有谁知道什么是SQL查询的DBIx :: Class等价物,例如:
SELECT cdr_id,CASE WHEN service_id ='GPRS'THEN'KB'When service_id ='SMS'THEN'SMS'END as AS FROM FROM ...
谢谢
我不认为我理解的范围DBIx::Class
我是否必须首先使用常规SQL手动创建数据库,然后使用模式加载器(或手动编写模式/结果集)?
或者有没有办法告诉DBIx::Class你继续从手动编码的模式和结果集创建表?
我问b/c是否需要通过SQL CREATE TABLE语句创建数据库,我的列基本上是在ResultSet代码中重复的,或者我需要依赖于schemaloader,我认为这种方法效率低且不适合生产.