DBIC模式加载器:如何跳过列

时间:2013-09-01 23:24:27

标签: mysql perl skip dbix-class

我有一个MySQL DB,在这些表上有多个表和视图。视图限制了单个客户数据(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

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

3 个答案:

答案 0 :(得分:1)

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

__PACKAGE__->remove_column('customer_id');

答案 1 :(得分:0)

我不确定DBIC :: Schema :: Loader中是否有选项,文档会告诉你。如果不仅生成模式,然后删除列定义。

但除此之外,您似乎错过了DBIC的一个主要功能:ResultSet链接。 如果你正在使用例如Catalyst你有一个动作,根据客户ID过滤你的存储上的ResultSet,所有链接的子动作只会看到允许的行。

答案 2 :(得分:0)

我最后只是将列留下了它,因此应用程序代码可以看到它。数据库视图和触发器确保应用程序只能插入和选择当前设置的客户ID。我使用的唯一技巧是使用filter_generated_code将基础表名替换为视图名(仅剥离前导下划线)。这样我现在有一个执行show tables的脚本,过滤掉视图,将结构转储到DBIC类中,用视图名称替换表名,看起来有点像这样:

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}'