2016-12-14 3 views
1

sqlalchemy로 액세스중인 기존 sqllite 테이블이 있습니다. 깨달은 많은 중복 '사례'숫자가 있습니다. 만약 내가 제대로 이해하고 당신이 사용 DUPS을 제거한 후, sqllite 테이블 생성 한 후 테이블에 고유 제한 조건을 추가 할 수 없습니다 나타납니다 : I 추가 DUPS의 추가를 방지하기 위해 SQLAlchemy의를 사용하는기존 sqllite 테이블에서 sqlalchemy로 중복 항목 방지

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

을 결정했습니다. 나는 scrapy 작업과 같은 보이는 파이프 라인의 요소가있어 :

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에서 작동합니다. 난 당신의 코드 논리 사이에 큰 차이를 보지 않았다

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

: 같은

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) 

그리고 두 번째 실행에 대한 출력

이 될 것입니다. 유일한 차이점은 내가 생각하는 버전 일 수 있습니다.

+0

감사합니다. 파이썬 2.7 및 sqlalchemy 1.014를 사용하고 있습니다. 나는 이것이 내가 가지고있는 기존의 테이블과 관련이 있는지 궁금해하고있다. 사례를 고유 한 테이블을 처음 만들었습니까? – user61629

+0

나는 내 코드를 테스트했고 예상대로 새 테이블을 만들 때 dup을 거부했다. 하지만 기존 테이블은 sqllite로 변경할 수 없다고 생각합니다. – user61629

+0

예, 테이블을 제거하고 다시 만들어야합니다. 그렇지 않으면 sqlalchemy-migrate를 사용하여 스키마를 업데이트 할 수 있습니다. – ichbinblau

관련 문제