2012-02-15 60 views
5

私はsqlalchemyを使用してサードパーティ製の既存のデータベースを使用しています。しかし、テーブルにはプライマリキーがないので問題があります。さらに悪いことに、各行に重複する要素があるため、既存の列をプライマリキーとして選択することはできません。表には2つの列があります。どちらも一意でない値を持ちます。Pythonの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列は見つかりません。私が間違っていることに関するアイデアは?前もって感謝します。

EDIT:要求されたように、ここで(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 
+0

あなたは例のデータを持つテーブルを投稿できるしてください? – JackalopeZero

+0

完了:現在どのような種類のデータがあるかのサンプルがあります。 – Einar

+0

ORMは行のIDとして機能するものがなければ動作しません。テーブルをクラスにマッピングせずに直接使用することを検討してください。 –

答えて

6

あなたがあなたが参照した投稿を誤解しました。 の既存の列を選択してプライマリとして定義する必要があります。複合プライマリ・キーをすべて定義して設定することも可能です。あなたの場合、遺伝子には成熟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)) 

テーブルのフィールドの種類がわからないので、整数でない場合は適切に変更してください。

+0

素晴らしい作品です。私はそれに応じて型を設定し、正しい結果を得るようになりました(sqlite3を使用した標準クエリと比較して)。 – Einar

+0

質問の更新データによれば、これらのペアは一意ではないため、プライマリキーとして機能することはできません。 ORMの一部は単純なクエリのように機能し、一部のものは無効なリロードで不正行為をする可能性があります。しかし、すべてがうまくいくとは思わないでください。 –

+0

私は主に等価性とINを使用しています(これは本当にシンプルなユースケースです)が、私はいくつかの正確なテストを行うつもりです。 – Einar

0

ID列を使用すると、両方の大文字と小文字を試みたことが最初オフとが存在することを確認してください。

テーブルのための2つの主キーを設定することも可能である:他の行は、まさにこの行と一致する場合

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

しかし、これは、更新異常を引き起こす可能性があります。テーブルを再作成して独自のPKカラムを挿入するのが最も良いかもしれません。

+0

私はそれをすることができますが、私はこれを避けるようにしたいと思います。なぜなら、それはサードパーティーから来て、そのようなデータベースをすべて忘れてしまいます。また、両方の列(exept私は猿パッチにしようとする)値が重複している(はい、混乱が、私はしなかった...)。編集:言うことを忘れて、 "ID"の列は存在しません。私は質問にリンクしている例を猿のパッチに当てはめましたが、それはうまくいきませんでした。 – Einar

0

変更列IDへのSQLiteデータベースのを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) 
関連する問題