2016-12-14 8 views
1

私はsqlalchemyでアクセスしている既存のsqlliteテーブルを持っています。私は、いくつかの重複した「ケース」番号が存在することを認識しました。私が正しく理解していれば、あなたが使用してDUPを取り除いた後、sqlliteを持つテーブルを作成した後、テーブルに一意性制約を追加することができないことが表示されます:私は、追加のアップデートパッケージの追加を防ぐために、SQLAlchemyのを使用する既存のsqlliteテーブルのsqlalchemyによる重複エントリの防止

DELETE FROM mytable 
WHERE id NOT IN 
(
SELECT MIN(id) 
FROM judgements 
GROUP BY "case" 

を決めました。私はscrapyでの作業とのように見えるパイプラインの要素持っている:私が作った唯一の変更は、ユニーク= Trueの欄に「ケース」を追加することです

class DynamicSQLlitePipeline(object): 

    def __init__(self,table_name): 
     db_path = "sqlite:///"+settings.SETTINGS_PATH+"\\data.db" 
     _engine = create_engine(db_path) 
     _connection = _engine.connect() 
     _metadata = MetaData() 
     _stack_items = Table(table_name, _metadata, 
          Column("id", Integer, primary_key=True), 
          Column("case", Text , unique=True), 
           ....) 
     _metadata.create_all(_engine) 
     self.connection = _connection 
     self.stack_items = _stack_items 



    def process_item(self, item, spider): 

     try: 
      ins_query = self.stack_items.insert().values(
      case=item['case'], 
      .... 
      ) 
      self.connection.execute(ins_query) 
     except IntegrityError: 
       print('THIS IS A DUP') 
     return item 

を。しかし、テストでは、dupsはまだ追加されている/私はこれを動作させることができますか?

答えて

1

以下のコードスニペットはPythonバージョン2.7とsqlalchemyバージョン1.0.9とsqliteバージョン3.15.2の私の側で動作します。

from sqlalchemy import create_engine, MetaData, Column, Integer, Table, Text 
from sqlalchemy.exc import IntegrityError 


class DynamicSQLlitePipeline(object): 

    def __init__(self, table_name): 
     db_path = "sqlite:///data.db" 
     _engine = create_engine(db_path) 
     _connection = _engine.connect() 
     _metadata = MetaData() 
     _stack_items = Table(table_name, _metadata, 
          Column("id", Integer, primary_key=True), 
          Column("case", Text, unique=True),) 
     _metadata.create_all(_engine) 
     self.connection = _connection 
     self.stack_items = _stack_items 

    def process_item(self, item): 

     try: 
      ins_query = self.stack_items.insert().values(case=item['case']) 
      self.connection.execute(ins_query) 
     except IntegrityError: 
       print('THIS IS A DUP') 
     return item 

if __name__ == '__main__': 

    d = DynamicSQLlitePipeline("pipeline") 
    item = { 
     'case': 'sdjwaichjkneirjpewjcmelkdfpoewrjlkxncdsd' 
    } 
    print d.process_item(item) 

そしてセカンドランのための出力は次のようになります:

THIS IS A DUP 
{'case': 'sdjwaichjkneirjpewjcmelkdfpoewrjlkxncdsd'} 

私はあなたのコードのロジックの間に大きな差は見ませんでした。唯一の違いは、私が推測するバージョンかもしれません。

+0

ありがとうございました。私はpython 2.7とsqlalchemyを1.014に使用しています。私はこれが私がここにある既存のテーブルと何か関係があるのだろうかと思っています。最初にケースをユニークにしてテーブルを作成したことがありますか? – user61629

+0

私は私のコードをテストし、私は期待どおりに動作し、dupを拒否する新しいテーブルを作成するとき。しかし、私が推測する既存のテーブルはsqlliteで変更することはできません。 – user61629

+0

はい、テーブルを削除して再度作成する必要があります。それ以外の場合は、sqlalchemy-migrateを使用してスキーマを更新できます。 – ichbinblau

関連する問題