各データベース バックエンドは、さまざまな種類のデータをサポートしています。sqlite および mysqldb python モジュールは、フィールドの型に基づいて適切な型変換を行うことで、あなたを助けようとします。そのため、mysql データベースに DECIMAL フィールドがある場合、MySQLdb はそのフィールドを Python Decimal オブジェクトとして自動的に返します。
MySQLdb (および必要に応じて sqlite) に、データベースと Python の型の間で適切な型変換を行うように要求できます。どの型変換が適切かを判断するのはあなた次第です。たとえば、データベースには DECIMAL フィールドがあるため、ネイティブの DECIMAL フィールドを持たない sqlite でその値をどのように表現するのでしょうか? おそらく REAL を使用することになりますが、もちろん、これは必要な精度を維持する DECIMAL と同じではありません。
あなたはすでに csv データから変換していたので、Python の float 型を使用していたのではないかと思います。これは、MySQL の 10 進フィールドを float に変換することに満足していることを示しています。この場合、MySQLdb がすべてのフィールド結果で DECIMAL から float への変換を行うように要求できます。
mysqldb と sqlite にそれぞれ 1 つずつ、2 つのテーブルを作成するコードの例を次に示します。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 が Decimal 型を返しているが、sqlite での使用に適した別の型を返すように強制できることです。
次に、2 つのデータベース間ですべての型を正規化すると、結合に関する問題は発生しなくなります。
Python MySQLdb ドキュメントはこちら