BioSQL 是 OBF 项目(BioPerl、BioJava 等)之间的一项合作努力,旨在支持用于存储序列数据的共享数据库模式。理论上,您可以使用 BioPerl 将 GenBank 文件加载到数据库中,然后使用 Biopython 从数据库中提取此文件作为带有特征的记录对象 - 并且获得的结果与直接将 GenBank 文件加载为 SeqRecord 对象(使用 SeqIO)的结果基本一致。
我们有一些现有的文档 (HTML,PDF),介绍 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,请检出他们的 git 仓库。或者,导航到您数据库的相应模式文件并仅下载该文件,例如,对于 MySQL,可以下载 biosqldb-mysql.sql。您还需要 NCBI 分类加载 Perl 脚本,load_ncbi_taxonomy.pl。
以下命令行应该在您自己的计算机上创建一个名为 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 用户而言:在将 biosqldb-pg.sql 模式加载到 Postgres 中之前,必须删除两个名为 rule_bioentry_i1 和 rule_bioentry_i2 的规则;biosqldb-pg.sql BioSQL 版本 1.0.1 中的第 771-791 行
首先,您需要设置用户权限,如果您不确定如何操作,请尝试以下操作
su - postgres
createuser <your user name>
然后,假设您以以下身份登录
createdb biosqldb
psql biosqldb < biosqldb-pg.sql
运行 psql 并输入 *\d
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() 函数应该已返回已加载的记录数(本示例中为三个),并且您再次查看数据库,您应该在几个表中看到新行。
bioentry 和 biosequence 表应该有三个新行
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 文档,从他们的 模式概述 和 注释映射 页面开始。
如果您遇到超时错误,请检查您的 SQL 服务器是否有任何孤立的线程。
mysql --user=root -p bioseqdb -e "SHOW INNODB STATUS\G" | grep "thread id"
如果有的话,假设您是唯一使用此数据库的人,您可以尝试使用上面命令给出的线程 ID 将它们杀死
mysql --user=root -p bioseqdb -e "KILL 123;"
请谨慎使用!