1

我有一个 MySQL 数据库,其中包含多个表和这些表上的视图。视图将可以看到的内容限制为单个客户的数据 ( create view ... where customer_id = X)。Catalyst 应用程序将与这些视图对话,而不是与实际表对话。视图的列和基础表的列之间的唯一区别是视图缺少customer_id列(即,对于应用程序来说,当前客户似乎是系统中唯一的客户)。

问题是,我不能使用 DBIC Schema Loader 从视图中加载模式,因为它们缺少所有的关系和键。我必须从基表中加载模式,然后在视图上使用它。问题是,我无法摆脱那个customer_id专栏。我需要摆脱它,因为它不存在于应用程序将与之交谈的视图中。

我最终使用该filter_generated_code选项从生成的代码中去除不需要的位,但随后在生成过程中出现以下错误:

DBIx::Class::Schema::Loader::make_schema_at(): No such column customer_id
at /opt/merp/perl/lib/perl5/Catalyst/Helper/Model/DBIC/Schema.pm line 635

如何让加载程序在加载时跳过某些列?

4

3 回答 3

1

我不确定如何让加载程序在加载时跳过列,但您可以在加载后删除它们。例如,您可以将这样的内容添加到需要删除列的任何类中:

__PACKAGE__->remove_column('customer_id');
于 2013-09-02T15:15:21.920 回答
0

I ended up just leaving the column for what it is, so it is visible to the application code. The DB views and triggers ensure the application can only insert and select the currently set customer id. The only trick I employed was using filter_generated_code to replace the underlying table name with the view name (just stripping a leading underscore). This way I now have a script that does a show tables, filters out the views, dumps the structure into the DBIC classes, replacing the table name with the view name, looking somewhat like this:

exclude=`mysql -u user -ppassword -D db --execute='show tables' \
--silent --skip-column-names | egrep "^_" | sed "s/^_//g" | \
sed ':a;N;$!ba;s/\n/|/g'`

perl script/proj_create.pl model DB DBIC::Schema Proj::Schema \
create=static components=TimeStamp filter_generated_code=\
'sub { my ($type,$class,$text) = @_; $text =~ s/([<"])_/$1/g; return $text; } ' \
exclude="^($exclude)$" dbi:mysql:db 'user' 'password' quote_names=1 '{AutoCommit => 1}'
于 2013-09-09T18:50:35.017 回答
0

我不确定 DBIC::Schema::Loader 中是否有这样的选项,文档会告诉你。如果不只是生成架构,然后删除列定义。

但除此之外,您似乎还缺少 DBIC 的一个主要特性:ResultSet 链接。如果您使用的是例如 Catalyst,您将有一个操作根据客户 ID 过滤存储中的 ResultSet,并且所有链接的子操作只会看到允许的行。

于 2013-09-07T11:39:15.590 回答