私は自分自身の質問に対して幾分不満足な答えがあります。私はPythonを使用して外部のOracleデータベースを照会してSQLに入れています。テーブルとカラムの名前の形式はかなりうまくいくと信じていますので、手順全体をPythonコードで囲み、Pythonでテーブルの検査に基づいてSQL更新クエリを更新します。多くの理由から
、私はまだこれを行うには良い方法を見てみたいと思いますが、ので、それは私の作品:私は、データベースを調べることができ、外部のスクリプト言語を使用してい
- とにかくスキーマ。
- 私が作業しているデータベース、列、およびテーブル名は、私が直接制御できるすべてのものなので、正常に動作すると信じています。
- 私の解決方法は、ローカルのSQLテーブル構造によって異なります。具体的にどのキーが主キーであるかを示す。適切に構造化されたテーブルがなければ、コードは機能しません。しかし、これは問題ありません。私はPythonコードを動作させるためにMySQLテーブルを再構成することができるからです。
他の誰かがより洗練された汎用ソリューションを考えてもいいと思っていますが、同じ問題を抱えている人に自分のPythonコードを提供します私が上記で行った仮定。以下は
私はPythonで簡単なSQLクエリを実行するために使用するのpythonラッパーです:
import config, MySQLdb
class SimpleSQLConn(SimpleConn):
'''simplified wrapper around a MySQLdb.connection'''
def __init__(self, **kwargs):
self._connection = MySQLdb.connect(host=config.mysql_host,
user=config.mysql_user,
passwd=config.mysql_pass,
**kwargs)
self._cursor = self._connection.cursor()
def query(self, query_str):
self._cursor.execute(query_str)
self._connection.commit()
return self._cursor.fetchall()
def columns(self, database, table):
return [x[0] for x in self.query('DESCRIBE `%s`.`%s`' % (database, table))g]
def primary_keys(self, database, table):
return [x[0] for x in self.query('DESCRIBE `%s`.`%s`' % (database, table)) if 'PRI' in x]
そしてここでは、実際の更新機能である、上記のSQLラッパークラスを使用して:
def update_table(database,
table,
mysql_insert_with_dbtable_placeholder):
'''update a mysql table without first deleting all the old records
mysql_insert_with_dbtable_placeholder should be set to a string with
placeholders for database and table, something like:
mysql_insert_with_dbtable_placeholder = "
INSERT INTO `%(database)s`.`%(table)s` VALUES (a, b, c);
note: code as is will update all the non-primary keys, structure
your tables accordingly
'''
sql = SimpleSQLConn()
query ='DROP TABLE IF EXISTS `%(database)s`.`%(table)s_temp_for_update`' %\
{'database': database, 'table': table}
sql.query(query)
query ='CREATE TABLE `%(database)s`.`%(table)s_temp_for_update` LIKE `%(database)s`.`%(table)s`'%\
{'database': database, 'table': table}
sql.query(query)
query = mysql_insert_with_dbtable_placeholder %\
{'database': database, 'table': '%s_temp_for_update' % table}
sql.query(query)
query = '''DELETE FROM `%(database)s`.`%(table)s` WHERE
(%(primary_keys)s) NOT IN
(SELECT %(primary_keys)s FROM `%(database)s`.`%(table)s_temp_for_update`);
''' % {'database': database,
'table': table,
'primary_keys': ', '.join(['`%s`' % key for key in sql.primary_keys(database, table)])}
sql.query(query)
update_columns = [col for col in sql.columns(database, table)
if col not in sql.primary_keys(database, table)]
query = '''INSERT into `%(database)s`.`%(table)s`
SELECT * FROM `%(database)s`.`%(table)s_temp_for_update`
ON DUPLICATE KEY UPDATE
%(update_cols)s
''' % {'database': database,
'table': table,
'update_cols' : ',\n'.join(['`%(table)s`.`%(col)s` = `%(table)s_temp_for_update`.`%(col)s`' \
% {'table': table, 'col': col} for col in update_columns])}
sql.query(query)
あなたが見ています複製に? – Strawberry
外国の低速なデータベースを、あまりアドホックな方法で複製することを意味するなら、それは私が考えていたものではありません。残念ながら、私のケースでは、それは多くの理由のための実用的な解決策ではないと思います: –
1つは、外部データベースはOracleで、ローカルデータベースはMySQLです。ローカルでは、完全な外部SQLサーバーを複製するためのリソースがありません。また、Oracleデータベース・サーバーのライセンスを取得して実行することもできます。 –