我可以在 DBIx::Class 中漂亮地打印 DBIC_TRACE 输出吗?

发布于 2024-07-13 08:53:28 字数 349 浏览 4 评论 0原文

将 DBIC_TRACE 环境变量设置为 true:

BEGIN { $ENV{DBIC_TRACE} = 1 }

生成非常有用的输出,特别是显示正在执行的 SQL 查询,但 SQL 查询全部在一行中。

有没有办法将它推入某种“sql tidy”例程以更好地格式化它,也许将它分成多行? 如果做不到这一点,任何人都可以给我一个提示,告诉我需要在代码中添加这样一个钩子吗? 接受格式错误的 SQL 查询并推出格式良好的查询的最佳工具是什么?

在这种情况下,“良好的格式”只是意味着比“全部都在一行上”更好。 我并不特别关心格式化查询的特定样式

谢谢!

Setting the DBIC_TRACE environment variable to true:

BEGIN { $ENV{DBIC_TRACE} = 1 }

generates very helpful output, especially showing the SQL query that is being executed, but the SQL query is all on one line.

Is there a way to push it through some kinda "sql tidy" routine to format it better, perhaps breaking it up over multiple lines? Failing that, could anyone give me a nudge into where in the code I'd need to hack to add such a hook? And what the best tool is to accept a badly formatted SQL query and push out a nicely formatted one?

"nice formatting" in this context simply means better than "all on one line". I'm not particularly fussed about specific styles of formatting queries

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

作死小能手 2024-07-20 08:53:28

从 DBIx::Class 0.08124 开始,它是内置的。

只需设置 $ENV{DBIC_TRACE_PROFILE}consoleconsole_monochrome

As of DBIx::Class 0.08124 it's built in.

Just set $ENV{DBIC_TRACE_PROFILE} to console or console_monochrome.

囚你心 2024-07-20 08:53:28

来自 DBIx::Class::Storage 的文档

如果设置了 DBIC_TRACE,则会生成跟踪信息(就像当
已设置调试方法)。

...

debug
导致在 debugobj 上发出跟踪信息
目的。 (如果没有专门设置 debugobj,则为 STDERR)。

debugobj
设置或检索用于度量收集的对象。
默认为 DBIx::Class::Storage::Statistics 的实例,即
与使用 coderef 作为回调的原始方法兼容。
有关详细信息,请参阅前面提到的统计类。

换句话说,您应该将该类中的 debugobj 设置为子类 DBIx::Class::Storage::Statistics。 在您的子类中,您可以按照您想要的方式重新格式化查询。

From the documentation of DBIx::Class::Storage

If DBIC_TRACE is set then trace information is produced (as when the
debug method is set).

...

debug
Causes trace information to be emitted on the debugobj
object. (or STDERR if debugobj has not specifically been set).

debugobj
Sets or retrieves the object used for metric collection.
Defaults to an instance of DBIx::Class::Storage::Statistics that is
compatible with the original method of using a coderef as a callback.
See the aforementioned Statistics class for more information.

In other words, you should set debugobj in that class to an object that subclasses DBIx::Class::Storage::Statistics. In your subclass, you can reformat the query the way you want it to be.

烏雲後面有陽光 2024-07-20 08:53:28

首先谢谢各位指点! 部分答案如下......

到目前为止我得到了什么......首先是一些脚手架:

# Connect to our db through DBIx::Class
my $schema = My::Schema->connect('dbi:SQLite:/home/me/accounts.db');

# See also BEGIN { $ENV{DBIC_TRACE} = 1 }
$schema->storage->debug(1);

# Create an instance of our subclassed (see below)
# DBIx::Class::Storage::Statistics class
my $stats = My::DBIx::Class::Storage::Statistics->new();

# Set the debugobj object on our schema's storage
$schema->storage->debugobj($stats);

My::DBIx::Class::Storage::Statistics 的定义是:

package My::DBIx::Class::Storage::Statistics;

use base qw<DBIx::Class::Storage::Statistics>;
use Data::Dumper qw<Dumper>;
use SQL::Statement;
use SQL::Parser;

sub query_start {
    my ($self, $sql_query, @params) = @_;

    print "The original sql query is\n$sql_query\n\n";

    my $parser = SQL::Parser->new();
    my $stmt   = SQL::Statement->new($sql_query, $parser);
    #printf "%s\n", $stmt->command;

    print "The parameters for this query are:";
    print Dumper \@params;
}

这解决了如何挂钩的问题获取 SQL 查询以供我“美化”。

然后我运行一个查询:

my $rs = $schema->resultset('SomeTable')->search(
    {   
        'email' => $email,
        'others.some_col' => 1,
    },
    { join => 'others' }
);
$rs->count;

但是 SQL::Parser 对 DBIx::Class 生成的 SQL 产生了错误:

The original sql query is
SELECT COUNT( * ) FROM some_table me LEFT JOIN others other_table ON ( others.some_col_id = me.id ) WHERE ( others.some_col_id = ? AND email = ? )

SQL ERROR: Bad table or column name '(others' has chars not alphanumeric or underscore!

SQL ERROR: No equijoin condition in WHERE or ON clause

那么...是否有比 SQL::Parser 更好的解析器来完成这项工作?

First, thanks for the pointers! Partial answer follows ....

What I've got so far ... first some scaffolding:

# Connect to our db through DBIx::Class
my $schema = My::Schema->connect('dbi:SQLite:/home/me/accounts.db');

# See also BEGIN { $ENV{DBIC_TRACE} = 1 }
$schema->storage->debug(1);

# Create an instance of our subclassed (see below)
# DBIx::Class::Storage::Statistics class
my $stats = My::DBIx::Class::Storage::Statistics->new();

# Set the debugobj object on our schema's storage
$schema->storage->debugobj($stats);

And the definition of My::DBIx::Class::Storage::Statistics being:

package My::DBIx::Class::Storage::Statistics;

use base qw<DBIx::Class::Storage::Statistics>;
use Data::Dumper qw<Dumper>;
use SQL::Statement;
use SQL::Parser;

sub query_start {
    my ($self, $sql_query, @params) = @_;

    print "The original sql query is\n$sql_query\n\n";

    my $parser = SQL::Parser->new();
    my $stmt   = SQL::Statement->new($sql_query, $parser);
    #printf "%s\n", $stmt->command;

    print "The parameters for this query are:";
    print Dumper \@params;
}

Which solves the problem about how to hook in to get the SQL query for me to "pretty-ify".

Then I run a query:

my $rs = $schema->resultset('SomeTable')->search(
    {   
        'email' => $email,
        'others.some_col' => 1,
    },
    { join => 'others' }
);
$rs->count;

However SQL::Parser barfs on the SQL generated by DBIx::Class:

The original sql query is
SELECT COUNT( * ) FROM some_table me LEFT JOIN others other_table ON ( others.some_col_id = me.id ) WHERE ( others.some_col_id = ? AND email = ? )

SQL ERROR: Bad table or column name '(others' has chars not alphanumeric or underscore!

SQL ERROR: No equijoin condition in WHERE or ON clause

So ... is there a better parser than SQL::Parser for the job?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文