【问题标题】:Python sqlalchemy : table with no primary keys and duplicate values?Python sqlalchemy:没有主键和重复值的表?
【发布时间】:2012-02-15 10:04:10
【问题描述】:

我正在使用由第三方通过 sqlalchemy 创建的现有数据库。但是,我遇到了麻烦,因为表没有主键,更糟糕的是,它们的每一行都有重复的元素,所以我不能选择现有的列作为主键。这些表有两列:都有非唯一值。

我尝试按照http://www.blog.pythonlibrary.org/2010/09/10/sqlalchemy-connecting-to-pre-existing-databases/ 对表格进行猴子修补,但显然这不起作用(见下文)

我当前的代码是(MirnaTable 是我的映射类,基本上只是一个骨架,没有别的)

connection = create_engine("sqlite:///targets.sqlite")
metadata = MetaData(bind=connection)
db_table = Table("miranda", metadata,
                 Column("id", Integer, primary_key=True),
                 autoload=True)
mapper(MirnaTable, db_table)
Session = sessionmaker(connection)
session = Session()

然后我尝试例如发布

all_records = session.query(MirnaTable).all()

我得到了

sqlalchemy.exc.OperationalError: (OperationalError) no such column: miranda.id 
u'SELECT miranda.gene_id AS miranda_gene_id, miranda."mature_miRNA" AS
"miranda_mature_miRNA", miranda.id AS miranda_id \nFROM miranda' ()

所以当然找不到 id 列。关于我做错了什么的任何想法?提前致谢。

编辑:根据要求,这是表中的一个示例(直接从 sqlite 检索):

gene  mature_miRNA 
---- -------------
80205  hsa-miR-200c 
80205  hsa-miR-200c 
9693  hsa-miR-200c 
9693  hsa-miR-200c 
9881  hsa-miR-200c 
9710  hsa-miR-200c 
9750  hsa-miR-200c 

【问题讨论】:

  • 能否请您发布带有示例数据的表格?
  • 完成:您现在可以期待什么样的数据样本。
  • 如果没有可以用作行标识的东西,ORM 将无法工作。考虑直接使用表而不将其映射到类。

标签: python sqlalchemy


【解决方案1】:

您误解了您所指的帖子。您必须选择一个现有 列并将其定义为主要列。也可以通过将它们全部放在定义中来设置复合主键。在你的情况下,我认为一个基因有几个成熟的 microRNA,所以主键可能应该由 (gene_id, mature_miRNA) 对组成。由于表中没有更多字段,因此autoload=True标志中不需要。

db_table = Table("miranda", metadata,
                 Column("gene_id", Integer, primary_key=True),
                 Column("mature_miRNA", Integer, primary_key=True))

我不知道你表中的字段类型,如果不是整数,请适当更改。

【讨论】:

  • 它很好用。我相应地设置了类型,现在我得到了正确的结果(与使用 sqlite3 的标准查询相比)。
  • 根据您在问题中更新的数据,这些对也不是唯一的,因此它们不能用作主键。 ORM 的某些部分(如简单查询)可以正常工作,而另一些部分可以通过禁用重新加载来欺骗。但不要指望一切都会奏效。
  • 我主要使用相等和IN(这是一个非常简单的用例),但我会做一些准确的测试以防万一。
【解决方案2】:

将 sqlite 数据库的列 id 更改为 rowid

原创

db_table = Table("miranda", metadata,
                 Column("id", Integer, primary_key=True),
                 autoload=True)

修改

db_table = Table("miranda", metadata,
                 Column("rowid", Integer, primary_key=True),
                 autoload=True)

【讨论】:

    【解决方案3】:

    请确保 id 列首先存在,然后您已尝试过大写和小写。

    也可以为表设置两个主键:

    Column("id", Integer, primary_key=True),
    Column("secondColumn", Integer, primary_key=True)
    

    但是,如果任何其他行与该行完全匹配,这可能会导致更新异常。您最好重新创建表格并插入您自己的 PK 列

    【讨论】:

    • 我可以这样做,但我会尽量避免这种情况,因为它来自第三方,这意味着分叉这样的数据库会出现所有问题。此外,两列(除了我尝试修补的那一列)都有重复的值(是的,一团糟,但我没有这样做......)。编辑:忘了说,“id”列不存在。我按照问题中链接的示例对表格进行了猴子修补(但它没有用)。
    猜你喜欢
    • 1970-01-01
    • 2017-07-13
    • 2013-05-09
    • 2012-05-18
    • 2012-02-16
    • 2021-05-15
    • 2022-10-06
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多