简体   繁体   English

在Perl中创建我自己的DBI :: Iterator实现

[英]Creating my own implementation of DBI::Iterator in perl

UPDATE: 更新:

Right now I am trying to take in to an array around 120M of rows. 现在,我正在尝试使用约120M行的数组。 Reason I'm not doing this over UTL_file is because in our production server it requires oracle user access to write and move the written flat-file into our desired directory. 我之所以没有通过UTL_file执行此操作,是因为在我们的生产服务器中,它需要oracle用户访问权限才能写入并将写入的平面文件移动到所需的目录中。 Add in to the problem is that there are still a lot of text manipulations needed after extraction which I think is a job for Perl. 问题在于提取后仍然需要进行许多文本操作,我认为这对Perl来说是一项工作。

What I want to do right now is to write my own implementation of the DBI::Iterator and all other dependencies it may need; 我现在想做的是编写我自己的DBI :: Iterator实现以及它可能需要的所有其他依赖关系。 to be clear though, not necessarily all. 不过要清楚一点,不一定全部。 (like some methods only of DBI, then just idb_rows... just to get this running since I cannot install modules) (就像只有DBI的某些方法一样,然后只有idb_rows ...只是为了使它运行,因为我无法安装模块)

Original Question: 原始问题:

Good day, I'm relatively new to perl programming, A week ago I started receiving out of memory messages again in perl. 美好的一天,我对perl编程还比较陌生,一个星期前,我又开始在perl中收到内存不足的消息。 I was able to get around this before by switching to 64 bit perl. 通过切换到64位perl,我能够解决此问题。

I just found yesterday that the kernel of my production machine is not allowing me to use more than 4GB of memory (in my other production server I am able to load large amounts of data to memory) 昨天我才发现生产机器的内核不允许我使用超过4GB的内存(在我的其他生产服务器中,我能够将大量数据加载到内存中)

Here are my specific restrictions in my production server 这是我在生产服务器中的特定限制

  1. I am not allowed to install new modules of perl 我不允许安装perl的新模块
  2. I am allowed, in a way, to install them locally but I am having trouble 我可以以某种方式在本地安装它们,但是遇到了麻烦

What I intend to do now is to recreate this module. 我现在打算做的是重新创建此模块。 Iterator::DBI 迭代器:: DBI

I have no background of iterators. 我没有迭代器的背景。 for the longest time I develop database extractions and ETL processes through the function below. 在最长的时间内,我通过以下功能开发数据库提取和ETL流程。 It's my 1st time to encounter an out of memory error again after a year and a half of using the function below. 使用以下函数一年半后,这是我第一次遇到内存不足错误。

sub myDBI
{
    my ($filename) = @_; 
    my $query = "";
    unless(open(FILE,$filename))
    {
        Logger("[ ERR ] unable to open $SETTINGS{SQL_TRIGGER}\n");
        print
        die;
    }
    my @result=`sqlplus -S $SETTINGS{USER_NAME}/$SETTINGS{PASSWORD}\@$SETTINGS{DB_NAME} <<END
    SET HEADING OFF
    SET FEEDBACK OFF
    SET SERVEROUTPUT ON
    SET LINES 5000
    SET COLSEP "||"
    $query
    /
    `
    ;
    @result;
}

You have several options: 您有几种选择:

  • If you have local::lib installed, you can install CPAN modules like Iterator::DBI to a user directory. 如果您安装了local :: lib ,则可以将Iterator :: DBI之类的CPAN模块安装到用户目录中。 You'll just need to set some environment variables to specify which directory to use. 您只需要设置一些环境变量来指定要使用的目录。

     export PERL_MB_OPT='--install_base /home/username/perl5' export PERL_MM_OPT='INSTALL_BASE=/home/username/perl5' export PERL5LIB='/home/username/perl5/lib/perl5/i386-linux:/home/username/perl5/lib/perl5' export PATH="/home/username/perl5/bin:$PATH" 
  • You actually don't need Iterator::DBI. 您实际上不需要Iterator :: DBI。 That module just wraps an Iterator object around a DBI statement handle, which is an iterator itself. 该模块只是将Iterator对象包装在DBI语句句柄周围,后者本身就是一个迭代器。 So you can just use DBI directly to connect to the database. 因此,您可以直接使用DBI来连接数据库。 (Note that either way, you'll connect to the database directly rather than going through sqlplus.) (请注意,无论哪种方式,您都将直接连接到数据库,而不是通过sqlplus。)

     use DBI; my $dbh = DBI->connect(...); my $sth = $dbh->prepare($sql_query); $sth->execute(@params); # iterate while (my $row = $sth->fetchrow_arrayref) { ... } 
  • If you really want to use Iterator::DBI and you can't install the module, you can just copy the source code directly and put it in ./Iterator/DBI.pm relative to your application. 如果您真的想使用Iterator :: DBI而不能安装该模块,则可以直接复制源代码 ,并将其放置在相对于您的应用程序的./Iterator/DBI.pm But the problem with this is you'll need to get around the dependencies. 但这是您需要解决依赖关系的问题。 To do that I would replace exceptions with a simple die or croak , and replace Iterator with a closure (see chapter 5 of Higher Order Perl for how to do this). 为此,我将用一个简单的diecroak替换异常,并用一个闭包替换Iterator (有关如何执行此操作,请参见High Order Perl的第5章)。 This option looks quite difficult for a beginner Perl programmer. 对于初学者的Perl程序员来说,此选项看起来非常困难。

  • If you really can't get DBI working, you can pipe the sqlplus output to a file and iterate through the file. 如果您确实无法使DBI正常工作,则可以将sqlplus输出传递到文件中并遍历该文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM