连接到 sqlite 文件时强制只读
Force readonly when connecting to sqlite file
在许多前端,
我希望使用到从主服务器镜像的 sqlite3 文件的只读连接来执行我的脚本。
有没有办法让 DBI 做到这一点?
目前,我正在这样做:
$dbHand = DBI->connect("dbi:SQLite:dbname=$dbName", $dbUser, $dbPass, {
PrintError => 0,
RaiseError => 1,
AutoCommit => 1,
}) or die $DBI::errstr;
并获得完全访问权限。
- 我不是 perl 流利,我必须 maintain/evolve 现有
- (我不想处理文件权限)
刚设置
$dbHand ->{ReadOnly} = 1
如描述here
使用 sqlite_open_flags
属性,如 DBD::SQLite documentation 中所述:
use DBD::SQLite;
my $dbh = DBI->connect("dbi:SQLite:$dbfile", undef, undef, {
sqlite_open_flags => DBD::SQLite::OPEN_READONLY,
});
如果您尝试打开一个不存在的数据库(通常会创建一个新数据库)或者如果您尝试写入一个现有数据库,这将导致错误。
请注意,您必须显式 use DBD::SQLite;
才能使用常量 DBD::SQLite::OPEN_READONLY
。
请注意 DBI 提供 ReadOnly
句柄属性,但 DBD::SQLite 在 v1 之前不支持它。49_05:
use strict;
use warnings;
use Data::Dump;
use DBI;
my $db = 'foo.db';
unlink $db if -f $db;
my $dbh = DBI->connect("dbi:SQLite:dbname=$db",'','', {
RaiseError => 1,
ReadOnly => 1
});
$dbh->do( q{CREATE TABLE foo(id INTEGER, name TEXT)} );
$dbh->do( q{INSERT INTO foo VALUES(1, 'foo')} );
my $values = $dbh->selectall_arrayref( q{SELECT * FROM foo} );
dd $values;
输出:
[[1, "foo"]]
切换到 sqlite_open_flags => DBD::SQLite::OPEN_READONLY
会导致错误。
如果数据库不存在:
DBI connect('dbname=foo.db','',...) failed: unable to open database file
如果数据库存在:
DBD::SQLite::db do failed: attempt to write a readonly database
从 DBD::SQLite v1.49_05 开始,您还可以使用 ReadOnly
属性,但只能作为 connect
的选项。连接后设置属性不起作用并引发警告:
my $dbh = DBI->connect("dbi:SQLite:dbname=$db",'','', {
RaiseError => 1
});
$dbh->{ReadOnly} = 1;
输出:
DBD::SQLite::db STORE warning: ReadOnly is set but it's only advisory
在许多前端, 我希望使用到从主服务器镜像的 sqlite3 文件的只读连接来执行我的脚本。
有没有办法让 DBI 做到这一点?
目前,我正在这样做:
$dbHand = DBI->connect("dbi:SQLite:dbname=$dbName", $dbUser, $dbPass, {
PrintError => 0,
RaiseError => 1,
AutoCommit => 1,
}) or die $DBI::errstr;
并获得完全访问权限。
- 我不是 perl 流利,我必须 maintain/evolve 现有
- (我不想处理文件权限)
刚设置
$dbHand ->{ReadOnly} = 1
如描述here
使用 sqlite_open_flags
属性,如 DBD::SQLite documentation 中所述:
use DBD::SQLite;
my $dbh = DBI->connect("dbi:SQLite:$dbfile", undef, undef, {
sqlite_open_flags => DBD::SQLite::OPEN_READONLY,
});
如果您尝试打开一个不存在的数据库(通常会创建一个新数据库)或者如果您尝试写入一个现有数据库,这将导致错误。
请注意,您必须显式 use DBD::SQLite;
才能使用常量 DBD::SQLite::OPEN_READONLY
。
请注意 DBI 提供 ReadOnly
句柄属性,但 DBD::SQLite 在 v1 之前不支持它。49_05:
use strict;
use warnings;
use Data::Dump;
use DBI;
my $db = 'foo.db';
unlink $db if -f $db;
my $dbh = DBI->connect("dbi:SQLite:dbname=$db",'','', {
RaiseError => 1,
ReadOnly => 1
});
$dbh->do( q{CREATE TABLE foo(id INTEGER, name TEXT)} );
$dbh->do( q{INSERT INTO foo VALUES(1, 'foo')} );
my $values = $dbh->selectall_arrayref( q{SELECT * FROM foo} );
dd $values;
输出:
[[1, "foo"]]
切换到 sqlite_open_flags => DBD::SQLite::OPEN_READONLY
会导致错误。
如果数据库不存在:
DBI connect('dbname=foo.db','',...) failed: unable to open database file
如果数据库存在:
DBD::SQLite::db do failed: attempt to write a readonly database
从 DBD::SQLite v1.49_05 开始,您还可以使用 ReadOnly
属性,但只能作为 connect
的选项。连接后设置属性不起作用并引发警告:
my $dbh = DBI->connect("dbi:SQLite:dbname=$db",'','', {
RaiseError => 1
});
$dbh->{ReadOnly} = 1;
输出:
DBD::SQLite::db STORE warning: ReadOnly is set but it's only advisory