Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl DBIx::类架构处理在内存中和磁盘上SQLite之间有所不同_Perl_Sqlite_Dbix Class_In Memory Database - Fatal编程技术网

Perl DBIx::类架构处理在内存中和磁盘上SQLite之间有所不同

Perl DBIx::类架构处理在内存中和磁盘上SQLite之间有所不同,perl,sqlite,dbix-class,in-memory-database,Perl,Sqlite,Dbix Class,In Memory Database,更新:解决了我的问题 我又一次被make_schema_的行为绊倒了,看到代码中关于@INC被修改的注释,我已经为此提交了一份bug报告 我在下面的代码中添加了我的第一条评论中提到的更正,即定义 my $dbic_schema = MySchema->connect( sub { $dbh } ); 在内存数据库中,make_schema_at断开与handle$dbh的连接时不起作用!可以通过将db句柄的克隆传递给make_schema_at来解决此问题。我也认为MaxyStudia

更新:解决了我的问题

我又一次被make_schema_的行为绊倒了,看到代码中关于@INC被修改的注释,我已经为此提交了一份bug报告

我在下面的代码中添加了我的第一条评论中提到的更正,即定义

my $dbic_schema = MySchema->connect( sub { $dbh } ); 
在内存数据库中,make_schema_at断开与handle$dbh的连接时不起作用!可以通过将db句柄的克隆传递给make_schema_at来解决此问题。我也认为MaxyStudiaAg的这种行为也是一种错误,但也许这是一个味觉的问题。我将对此进行讨论,并可能提交一份bug报告。我已决定添加程序的更新版本,以防其他人有相同的问题:

SQLite_test.pl

原始问题:

我想使用内存中的SQLite数据库来测试Perl模块。其思想是在DBD::SQLite提供的内存中SQLite数据库中创建一些表,使用DBIx::Class::schema::Loader将DBIx::Class架构转储到磁盘,加载生成的架构,并针对该架构进行测试。请参阅,例如,了解处理这样的DBIx::类模式的基本原理。我想使用内存中的数据库,因为我不想在用户安装模块时执行诸如写入磁盘之类的操作

我的问题是,使用这样一个内存中的数据库与使用磁盘上的SQLite数据库不同

我准备了一个完整的例子来说明我的意思,在这个例子中,把一行换成另一行会产生不同。假设在目录中我们有:

如果文件schema.sql的内容如下所示,并且创建了表T,则其内容应该是无关的 SQLite数据库SQLite_db还没有表T 程序SQLite_test.pl schema.sql:

SQLite_test.pl:

现在,如图所示运行程序SQLite_test.pl在第一次运行时有效,在下一次运行之前,显然需要删除表T,我不想使示例复杂化。但是,如果在1之后注释该行,并在2之后注释掉该行,则会出现以下错误,即找不到表T:

DBI Exception: DBD::SQLite::db prepare_cached failed: no such table: T [for Statement "SELECT COUNT( * ) FROM T me"] at
C:/strawberry/perl/site/lib/DBIx/Class/Schema.pm line 1101.
        DBIx::Class::Schema::throw_exception('MySchema=HASH(0x1e49df4)', 'DBI Exception: DBD::SQLite::db prepare_cached
failed: no such...') called at C:/strawberry/perl/site/lib/DBIx/Class/Storage.pm line 112
        DBIx::Class::Storage::throw_exception('DBIx::Class::Storage::DBI::SQLite=HASH(0x342c64c)', 'DBI Exception: DBD::
SQLite::db prepare_cached failed: no such...') called at C:/strawberry/perl/site/lib/DBIx/Class/Storage/DBI.pm line 1427

        DBIx::Class::Storage::DBI::__ANON__('DBD::SQLite::db prepare_cached failed: no such table: T [for ...', 'DBI::db
=HASH(0x3311c7c)', undef) called at C:/strawberry/perl/site/lib/DBIx/Class/Storage/DBI.pm line 2418 
...
你知道我忽略了什么吗


更新:环境是Windows 7/Perl 5.16.2.1。

像您一样连接到新的内存中的SQLite db,然后运行

$dbic_schema->deploy;
这将针对数据库生成并运行所有必需的DDL语句。 根本不需要使用DBIx::RunSQL,因为DBIx::Class已经包含了该功能


请注意,您需要安装SQL::Translator。

那么,您认为应该在哪里为内存表创建表T?我不太理解您的问题,但这让我重新思考。有一点似乎是错误的,当使用内存中的SQLite db时,在my$dbic_schema=MySchema->connect$dsn,q{},q{}行中;我连接到一个+新+数据库。我试图用我的$dbic_schema=MySchema->connect sub{$dbh}替换这一行来修复这个问题;但这仍然给了我一个错误DBI异常:DBD::SQLite::db prepare_cached失败:尝试在非活动数据库句柄上准备如何确保数据库句柄$dbh在使用DBIx::RunSQL创建时处于活动状态?总结/澄清我的上一条评论,要点是:1表T在一个数据库中创建,但随后我连接到另一个数据库2解决方案是在连接DBIx::Class schema$dbic_schema 3时使用数据库句柄连接原始数据库。如我在第一条评论中所述,重用$dbh不起作用……不活动的数据库句柄……我希望将该架构保留在数据库中,并从中派生DBIx::Class schema。这就是我首先使用DBIx::RunSQL的原因。您的建议适用于以DBIx::Class模式为起点的情况。这在DBIx::Class::schema::Loader中是可能的,它被称为“动态模式”。请注意,启动速度会慢得多,因为它必须每次扫描数据库并创建类。建议生成一次并将其转储到磁盘。请阅读DBIC手册。谢谢你的指点,我会研究一下,看看它是否更合适。关于一次性转储数据库模式,就我而言,当前启动时间是可以的。我现在不想用一个选项来控制是否需要刷新数据库模式转储,从而使用户界面复杂化,因为这也是需要的。
use strict;
use warnings;

use Test::More;

use DBI;
use DBIx::RunSQL;
use Class::Load qw (load_class);
use DBIx::Class::Schema::Loader qw/ make_schema_at /;
plan tests => 1;

my $table = 'T';

# (1) Using a database on disk works:
my $dsn = 'dbi:SQLite:dbname=sqlite_db';

# (2) Using an in-memory SQLite database not:
# my $dsn   = 'dbi:SQLite:dbname=:memory:';

#Create our test table in the target database
my $dbh = DBIx::RunSQL->create(
    dsn     => $dsn,
    sql     => 'schema.sql',
    force   => 0,
    verbose => 1,
);

#Dump the DBIx::Class Schema in the current directory
my $attrs = {
    debug          => 1,
    dump_directory => '.',
};

make_schema_at( 'MySchema', $attrs, [ sub { $dbh }, {} ] );

#Import the resulting Schema

#Note: in the current version, make_schema_at removes '.' from @INC,
#therefore we add it:
push @INC, '.';
eval {
    require MySchema;
    MySchema->import();
    1;
} or do {
    my $error = $@;
    croak $error;
};

#Connect to the Schema and use it to count the rows in table T
my $dbic_schema = MySchema->connect( $dsn, q{}, q{} );

my $result_source = $dbic_schema->source('T');
my $cls           = $result_source->result_class;

my $num_records = $dbic_schema->resultset($cls)->count;
is( $num_records, 5, 'check number of records' );
DBI Exception: DBD::SQLite::db prepare_cached failed: no such table: T [for Statement "SELECT COUNT( * ) FROM T me"] at
C:/strawberry/perl/site/lib/DBIx/Class/Schema.pm line 1101.
        DBIx::Class::Schema::throw_exception('MySchema=HASH(0x1e49df4)', 'DBI Exception: DBD::SQLite::db prepare_cached
failed: no such...') called at C:/strawberry/perl/site/lib/DBIx/Class/Storage.pm line 112
        DBIx::Class::Storage::throw_exception('DBIx::Class::Storage::DBI::SQLite=HASH(0x342c64c)', 'DBI Exception: DBD::
SQLite::db prepare_cached failed: no such...') called at C:/strawberry/perl/site/lib/DBIx/Class/Storage/DBI.pm line 1427

        DBIx::Class::Storage::DBI::__ANON__('DBD::SQLite::db prepare_cached failed: no such table: T [for ...', 'DBI::db
=HASH(0x3311c7c)', undef) called at C:/strawberry/perl/site/lib/DBIx/Class/Storage/DBI.pm line 2418 
...
$dbic_schema->deploy;