在 GitHub 上编辑此页面

使用 BioSQL 模块管理本地生物数据库。

BioSQLOBF 项目(BioPerl、BioJava 等)之间的一项合作努力,旨在支持用于存储序列数据的共享数据库模式。理论上,您可以使用 BioPerl 将 GenBank 文件加载到数据库中,然后使用 Biopython 从数据库中提取此文件作为带有特征的记录对象 - 并且获得的结果与直接将 GenBank 文件加载为 SeqRecord 对象(使用 SeqIO)的结果基本一致。

我们有一些现有的文档 (HTMLPDF),介绍 Biopython 与 BioSQL 的接口,涵盖安装 Python 数据库适配器以及 BioSQL 的基本用法。这些文档有些过时了,我希望利用这个 wiki 页面在将来更新上述文档。

以下文本适用于 Biopython 1.64 或更高版本(并假设使用 Python 3)。

安装

这相当复杂 - 部分原因是存在很多选项。例如,您可以使用多种不同的 SQL 数据库软件包(我们将重点介绍 MySQL),您可以在自己的计算机上(这里假设的情况)或独立的服务器上拥有数据库,并且当然,数据库还与用户名和密码相关联。最后,细节也会因您的操作系统而异。

本文本部分基于 BioSQL 模式安装说明,其中还介绍了 MySQL 的替代方案。

安装所需软件

您需要安装一些数据库软件以及相关的 Python 库,以便 Biopython 可以“连接”到数据库。在本示例中,我们将介绍最常用的选择,即 MySQL。具体的安装方法也会因您的操作系统而异,例如,在 Debian 或 Ubuntu Linux 机器上,您可以尝试以下操作

sudo apt install mysql-common mysql-server python3-mysqldb

登录需要密码。请参考 MySQL 文档

Python 还需要一个数据库驱动程序来访问 MySQL 数据库。在您的虚拟环境中

pip install mysql-connector-python

拥有 perl(用于运行某些设置脚本)也很重要。同样,在 Debian 或 Ubuntu Linux 机器上,您可以尝试以下操作

sudo apt-get install perl

您可能会发现 perl 已经安装好了。

对于 Windows 用户,请参阅 Windows 上的 BioSQL

下载 BioSQL 模式和脚本

安装完软件后,您的下一步任务是设置一个数据库并导入 BioSQL 模式(即在数据库中设置相关的表)。请参阅 BioSQL 下载 - 您需要解压缩存档。

或者,要获取最新的 BioSQL,请检出他们的 git 仓库。或者,导航到您数据库的相应模式文件并仅下载该文件,例如,对于 MySQL,可以下载 biosqldb-mysql.sql。您还需要 NCBI 分类加载 Perl 脚本,load_ncbi_taxonomy.pl

创建空数据库

MySQL

以下命令行应该在您自己的计算机上创建一个名为 bioseqdb 的新数据库,该数据库属于 root 用户帐户

mysqladmin -u root -p create biosqldb

然后,我们可以告诉 MySQL 加载我们上面下载的 BioSQL 模式。切换到解压缩的 BioSQL 下载的 scripts 子目录,然后

mysql -u root -p bioseqdb < biosqldb-mysql.sql

您可以使用 mysql 命令行工具快速试用一下,例如

mysql --user=root -p bioseqdb -e "show tables"

输出

+----------------------------+
| Tables_in_bioseqdb         |
+----------------------------+
| biodatabase                |
| bioentry                   |
| bioentry_dbxref            |
| bioentry_path              |
| bioentry_qualifier_value   |
| bioentry_reference         |
| bioentry_relationship      |
| biosequence                |
| comment                    |
| dbxref                     |
| dbxref_qualifier_value     |
| location                   |
| location_qualifier_value   |
| ontology                   |
| reference                  |
| seqfeature                 |
| seqfeature_dbxref          |
| seqfeature_path            |
| seqfeature_qualifier_value |
| seqfeature_relationship    |
| taxon                      |
| taxon_name                 |
| term                       |
| term_dbxref                |
| term_path                  |
| term_relationship          |
| term_relationship_term     |
| term_synonym               |
+----------------------------+

或者,要查看表内部

mysql --user=root -p bioseqdb -e "select * from bioentry;"

这应该不会返回任何行,因为表是空的。

PostgreSQL

注意:对于 PostgreSQL 用户而言:在将 biosqldb-pg.sql 模式加载到 Postgres 中之前,必须删除两个名为 rule_bioentry_i1rule_bioentry_i2 的规则;biosqldb-pg.sql BioSQL 版本 1.0.1 中的第 771-791 行

首先,您需要设置用户权限,如果您不确定如何操作,请尝试以下操作

su - postgres
createuser <your user name>

然后,假设您以以下身份登录并且 Postgres 在本地机器上运行,您应该能够执行以下操作

createdb biosqldb
psql biosqldb < biosqldb-pg.sql

运行 psql 并输入 *\d* 查看所有创建的实体。

NCBI 分类

BioSQL 包含一个位于 scripts/load_ncbi_taxonomy.pl 下的 Perl 脚本,用于下载和更新分类表。该脚本应该能够从 NCBI 分类 FTP 站点 自动下载它所需的文件。

在 Biopython 1.49 之前,如果您想使用 NCBI 分类数据库,最好在开始尝试将序列加载到数据库之前预加载 NCBI 分类。对于 Biopython 1.49 及更高版本,这一点并不那么重要,您可以选择在需要时从 Entrez 下载所需的信息。

要更新 NCBI 分类,请切换到解压缩的 BioSQL 下载的 scripts 子目录,然后

./load_ncbi_taxonomy.pl --dbname bioseqdb --driver mysql --dbuser root --download true

对于 PostgreSQL,您需要安装 perl DBD-Pg 模块 - 使用 CPAN:“perl -MCPAN -e ‘install DBI’; perl -MCPAN -e ‘install DBD::Pg’”。在上面的命令中,将 Pg 替换为 mysql

大约有 10 MB 的数据要获取,因此可能需要一段时间(并且在下载过程中不会给出任何反馈)。如果您担心,请打开一个文件浏览器窗口并检查它是否正在 taxdata 子目录中下载一个名为 taxdump.tar.gz 的文件。

您应该在命令提示符下看到以下输出 - 请注意,其中一些步骤确实需要一些时间(尤其是 重建嵌套集左右值

Loading NCBI taxon database in taxdata:
        ... retrieving all taxon nodes in the database
        ... reading in taxon nodes from nodes.dmp
        ... insert / update / delete taxon nodes
        ... (committing nodes)
        ... rebuilding nested set left/right values
        ... reading in taxon names from names.dmp
        ... deleting old taxon names
        ... inserting new taxon names
        ... cleaning up
Done.

这可能是您休息一下的好时机 - 我没有计时,但花费了十多分钟。

在初始表填充后,重新运行脚本会快得多。您可以再次运行此脚本以更新分类表,NCBI 会定期向其中添加内容。您可能希望设置一个计划任务以自动执行此操作(例如,每两周一次)。

附注:如果您将使用分类表中的左右值,那么更新分类特别有用(另请参阅 BioSQL 增强请求 GitHub 问题 14 (Redmine 2493))。Biopython 1.67 及更高版本在写入分类表时会执行此操作。

注意:Biopython 在加载或检索序列时会忽略这些可选字段 - 而是仅使用父链接。请参阅 http://www.oreillynet.com/pub/a/network/2002/11/27/bioconf.html,了解更多有关这种替代树表示方式的工作原理。

运行单元测试

由于您可以通过多种方式设置 BioSQL 数据库,因此您必须通过编辑 Tests/setup_BioSQL.py 文件并填写以下字段来告诉单元测试一些信息

DBDRIVER = "mysql.connector"
DBTYPE = "mysql"

以及更下面一点的

DBHOST = "localhost"
DBUSER = "root"
DBPASSWD = "your-password"
TESTDB = "biosql_test"

将这些更改为您设置的内容。然后,您可以像往常一样运行 BioSQL 单元测试,例如

python run_tests.py test_BioSQL test_BioSQL_SeqIO

对于 PostgreSQL,请使用

DBDRIVER = "psycopg2"
DBTYPE = "pg"

创建(子)数据库

BioSQL 允许我们在单个 SQL 数据库(我们在前面称之为 bioseqdb)中定义名为“子”数据库或“命名空间”。对于本示例,让我们为一些兰花序列创建一个命名空间

from BioSQL import BioSeqDatabase

server = BioSeqDatabase.open_database(
    driver="mysql.connector",
    user="root",
    passwd="your-password",
    host="localhost",
    db="bioseqdb",
)
db = server.new_database("orchids", description="Just for testing")
server.commit()

(如果您使用的是 PostgreSQL 而不是 MySQL,只需将驱动程序参数更改为“psycopg2”。本文档中的其他示例也是如此。)

commit 调用告诉数据库保存到目前为止的更改(提交 SQL 事务)。您可以自行决定何时提交 SQL 事务,以及回滚更改,而不是让 Biopython 尝试自行决定,并冒着出错的风险。请参阅 显式优于隐式 (Python 之禅)。

现在 biodatabase 表中应该只有一行用于我们的新兰花命名空间。您可以在命令行中检查这一点

MySQL

mysql --user=root -p bioseqdb -e "select * from biodatabase;"

PostgreSQL

psql -c "SELECT * FROM biodatabase;" bioseqdb

这应该会输出类似于以下内容(假设您还没有进行任何其他测试)

+----------------+---------+-----------+------------------+
| biodatabase_id | name    | authority | description      |
+----------------+---------+-----------+------------------+
|              1 | orchids | NULL      | Just for testing |
+----------------+---------+-----------+------------------+

现在,我们已经设置了 biosqldb MySQL 数据库中的 orchids 命名空间,让我们向其中添加一些序列。

将序列加载到数据库中

当使用 Biopython 将序列加载到 BioSQL 数据库时,我们必须提供带注释的 SeqRecord 对象。这又给了我们一个使用 SeqIO 模块的理由!以下是对将序列作为 SeqRecord 对象读取的快速回顾,它基于 Biopython 教程中的一个兰花示例

from Bio import Entrez
from Bio import SeqIO

handle = Entrez.efetch(
    db="nuccore", id="6273291,6273290,6273289", rettype="gb", retmode="text"
)
for seq_record in SeqIO.parse(handle, "genbank"):
    print(seq_record.id, seq_record.description[:50] + "...")
    print("Sequence length %i," % len(seq_record.seq))
    print("from: %s" % seq_record.annotations["source"])
handle.close()

预期的输出如下所示,请注意我们有三个记录,总共有九个特征

AF191665.1 Opuntia marenae rpl16 gene; chloroplast gene for c...
Sequence length 902, 3 features, from: chloroplast Opuntia marenae
AF191664.1 Opuntia clavata rpl16 gene; chloroplast gene for c...
Sequence length 899, 3 features, from: chloroplast Grusonia clavata
AF191663.1 Opuntia bradtiana rpl16 gene; chloroplast gene for...
Sequence length 899, 3 features, from: chloroplast Opuntia bradtianaa

现在,让我们将这三个记录添加到一个新的(空的)orchid 数据库中,而不是在屏幕上打印它们

from Bio import Entrez
from Bio import SeqIO
from BioSQL import BioSeqDatabase

server = BioSeqDatabase.open_database(
    driver="mysql.connector",
    user="root",
    passwd="your-password",
    host="localhost",
    db="bioseqdb",
)
db = server["orchids"]
handle = Entrez.efetch(
    db="nuccore", id="6273291,6273290,6273289", rettype="gb", retmode="text"
)
count = db.load(SeqIO.parse(handle, "genbank"))
print("Loaded %i records" % count)
server.commit()

同样,您必须显式调用 commit 来记录 SQL 事务,否则事务将处于挂起状态。

db.load() 函数应该已返回已加载的记录数(本示例中为三个),并且您再次查看数据库,您应该在几个表中看到新行。

bioentrybiosequence 表应该有三个新行

mysql --user=root bioseqdb -e "select * from bioentry;"
mysql --user=root bioseqdb -e "select * from biosequence;"

还应该有九个新特征

mysql --user=root -p bioseqdb -e "select * from seqfeature;"

接下来,我们将尝试从数据库中加载这三个记录。

从数据库中提取序列

本示例从前面的示例继续,我们在前面示例中将三个记录加载到 orchids 数据库(命名空间)中

from BioSQL import BioSeqDatabase

server = BioSeqDatabase.open_database(
    driver="mysql.connector",
    user="root",
    passwd="your-password",
    host="localhost",
    db="bioseqdb",
)
db = server["orchids"]
for identifier in ["6273291", "6273290", "6273289"]:
    seq_record = db.lookup(gi=identifier)
    print(seq_record.id, seq_record.description[:50] + "...")
    print("Sequence length %i," % len(seq_record.seq))

输出

AF191665.1 Opuntia marenae rpl16 gene; chloroplast gene for c...
Sequence length 902
AF191664.1 Opuntia clavata rpl16 gene; chloroplast gene for c...
Sequence length 899
AF191663.1 Opuntia bradtiana rpl16 gene; chloroplast gene for...
Sequence length 899

您从 BioSQL 获取的对象的行为类似于 SeqRecord 对象,其序列为 Seq 对象,但它们并不完全相同。您实际上获得的是它们的 BioSQL 数据库等效项,即带有 DBSeq 对象的 DBSeqRecord 对象,用于表示序列。这些对象仅在需要时才会从数据库中加载序列和注释。

还有其他方法可以提取记录 - 这里的“db”对象在一定程度上充当字典(包括支持从其键中删除条目)。Python 字典键实际上是数据库内部用于 bioentry 表的数据库主键。例如

from BioSQL import BioSeqDatabase

server = BioSeqDatabase.open_database(
    driver="mysql.connector",
    user="root",
    passwd="your-password",
    host="localhost",
    db="bioseqdb",
)
db = server["orchids"]
print("This database contains %i records" % len(db))
for key, record in db.iteritems():
    print("Key %r maps to a sequence record with id %s" % (key, record.id))

删除(子)数据库

如上所述,BioSQL 允许我们在单个 SQL 数据库(我们在前面称之为 bioseqdb)中定义名为“子”数据库(也称为命名空间)。在前面的示例中,我们为一些兰花序列创建了一个子数据库。以下代码将删除 orchid 数据库(以及其中的所有记录)

from BioSQL import BioSeqDatabase

server = BioSeqDatabase.open_database(
    driver="mysql.connector",
    user="root",
    passwd="your-password",
    host="localhost",
    db="bioseqdb",
)
server.remove_database("orchids")
server.commit()

同样,您必须显式地用 commit 结束 SQL 事务以应用此更改。

现在 biodatabase 表中应该少一行,可以在命令行中检查这一点

mysql --user=root -p bioseqdb -e "select * from biodatabase;"

您还可以检查这三个兰花序列是否已从其他表中删除。

数据是如何存储的

如果您需要或希望直接访问数据,绕过 Biopython 方法来检索记录,那么了解底层表的用法会很有帮助。为此,我们建议您参考 BioSQL 文档,从他们的 模式概述注释映射 页面开始。

MySQL 提示和技巧

如果您遇到超时错误,请检查您的 SQL 服务器是否有任何孤立的线程。

mysql --user=root -p bioseqdb -e "SHOW INNODB STATUS\G" | grep "thread id"

如果有的话,假设您是唯一使用此数据库的人,您可以尝试使用上面命令给出的线程 ID 将它们杀死

mysql --user=root -p bioseqdb -e "KILL 123;"

请谨慎使用!