2013-10-04 3 views
5

저는 MySQL 데이터베이스에서 가져 와서 처리하고 업데이트하는 Python 스크립트를 작성하고 있습니다.동일한 Python 2.7 스크립트에서 mysqldb 및 sqlite3 사용 : 수건을 던져야하나요?

나는이 문제를 쉼표로 구분 된 MySQL 데이터베이스의 값 덤프로 공격하기 시작했다. sqlite3를 사용하여 sqlite 데이터베이스에 던져 넣었다. 나는 파이썬 (2.7)에서 처리를하고, 다른 스크립트로 MySQL 데이터베이스로 다시 업로드 할 출력의 CSV 파일을 작성한다.

음, 그렇다면 필자는 Python 스크립트에서 직접 MySQL 데이터베이스로 직접 가져 오거나 푸시하려고한다고 생각했습니다. 그래서 MySQLdb를 설치하고 그곳에갔습니다.

내가 지금 알아 낸 것은 MySQL 데이터베이스의 (sqlite 데이터베이스로) INSERT이 이전의 방식에 합류하지 않는다는 것입니다. 정수 표현은 이제 끝에 붙는 L을 가지며 십진수 값은 Decimal('4.00')과 같이 표현됩니다.

기본적으로 CSV 파일에서 삽입했을 때 JOIN이 멋지게 편집되었다는 사실은 현재 잘 작동하지 않습니다.

내 질문 :이 경로를 계속 이어 나가고 싶지 않거나 MySQLdb와 sqlite3 라이브러리를 함께 사용할 수있는 쉬운 방법이 있습니까? 거기에 없다면, MySQL 서버를 설치하고 리팩터링하여 MySQL을 사용하는 코드 만 만들 것입니다.

+2

here이 아래로 투표를 한 이유 아무 생각이다. 나는 그것이 좋은 질문이고 +1 가치가 있다고 느낍니다. 그래서 .. +1. –

답변

5

각 데이터베이스 백엔드는 서로 다른 유형의 데이터를 지원합니다. sqlite 및 mysqldb python 모듈은 필드 유형에 따라 적절한 유형 변환을 수행하여 사용자를 도와줍니다. 따라서 mysql 데이터베이스에 DECIMAL 필드가 있으면 MySQLdb는 해당 필드를 자동으로 Python Decimal 객체로 반환합니다.

데이터베이스와 파이썬 유형간에 적절한 유형 변환을 수행하기 위해 MySQLdb (및 원하는 경우 sqlite)를 요청할 수 있습니다. 어떤 유형 변환이 적절한 지 결정하는 것은 당신에게 달려 있습니다. 예를 들어, 데이터베이스에 DECIMAL 필드가 있으므로 sqlite에서 기본 DECIMAL 필드가없는 값을 어떻게 나타낼 것입니까? 아마도 REAL을 사용하게 될 것입니다 만, 물론 이것이 필요한 정밀도를 유지하는 DECIMAL과 같은 것은 아닙니다.

이미 CSV 데이터에서 변환 중이므로 Python float 유형을 사용하고있는 것으로 의심됩니다. 이는 MySQL 십진수 필드를 float로 변환하는 것이 행복하다는 것을 나타냅니다. 이 경우, MySQLdb가 모든 필드 결과에 대해 DECIMAL에서 부동으로 변환하도록 요청할 수 있습니다.

다음은 mysqldb와 sqlite에 각각 하나씩 두 개의 테이블을 생성하는 예제 코드 비트입니다. MySQL 버전에는 DECIMAL 필드가 있습니다. query_dbs 함수에서 고유 한 변환 함수를 만드는 방법을 볼 수 있습니다.

#!/usr/bin/env python 

import os 
import sqlite3 
import MySQLdb 
from MySQLdb.constants import FIELD_TYPE 

user = os.getenv('USER') 

def create_mysql_table(): 
    conn = MySQLdb.connect(user=user, db='foo') 
    c = conn.cursor() 
    c.execute("DROP TABLE stocks") 
    c.execute("CREATE TABLE stocks" 
       "(date text, trans text, symbol text, qty real, price Decimal(10,2) UNSIGNED NOT NULL)") 
    c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") 
    conn.commit() 

def create_sqlite_table(): 
    conn = sqlite3.connect('test.db') 
    c = conn.cursor() 
    c.execute("DROP TABLE stocks") 
    c.execute("CREATE TABLE stocks" 
       "(date text, trans text, symbol text, qty real, price real)") 
    c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") 
    conn.commit() 

def query_dbs(use_type_converters): 
    conn = sqlite3.connect('test.db') 
    c = conn.cursor() 
    for row in c.execute('SELECT * FROM stocks'): 
     print 'SQLITE: %s' % str(row) 

    type_converters = MySQLdb.converters.conversions.copy() 

    if use_type_converters: 
     type_converters.update({ 
      FIELD_TYPE.DECIMAL: float, 
      FIELD_TYPE.NEWDECIMAL: float, 
     }) 

    conn = MySQLdb.connect(user=user, db='foo', conv=type_converters) 
    c = conn.cursor() 
    c.execute('SELECT * FROM stocks') 
    for row in c.fetchall(): 
     print 'MYSQLDB: %s' % str(row) 

create_sqlite_table() 
create_mysql_table() 

print "Without type conversion:" 
query_dbs(False) 
print "With type conversion:" 
query_dbs(True) 

이 스크립트는 내 컴퓨터에 다음과 같은 출력이 생성이 화면이 표시되어 어떤

Without type conversion: 
SQLITE: (u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.14) 
MYSQLDB: ('2006-01-05', 'BUY', 'RHAT', 100.0, Decimal('35.14')) 
With type conversion: 
SQLITE: (u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.14) 
MYSQLDB: ('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14) 

을 기본적으로 MySQLdb는 진수 형식을 반환하지만, 다른 유형을 반환하도록 강제 할 수있는, 적합 sqlite와 함께 사용하기.

그런 다음 두 데이터베이스간에 모든 유형의 정규화가 완료되면 더 이상 조인에 문제가 없어야합니다.

파이썬 MySQLdb의 문서는

+0

이것은 매우 유익합니다! 감사합니다! – John

2

sqlite3와 MySQLdb간에 충돌이 없으므로 동일한 프로그램에서 사용할 수 있어야합니다. 그러나 두 종류의 데이터베이스 모두에 고급 인터페이스를 제공하는 SQLAlchemy을 사용할 수도 있습니다.

실제로이 문제가 나타나는 이유는 숫자를 문자열로 잘못 변환 한 것입니다. 특히 str()이 아닌 repr()을 사용하고 있습니다.

+0

쿨; 내 여행에서 SQLAlchemy를 보았습니다. 또한 (오스틴의 답변에서) 형식 변환을 제어하는 ​​방법에 대해 알지 못했음이 나타납니다. (++) – John