0

SQL nodata ダンプがあり、それを調べて、各テーブル作成クエリのエンジン部分を置き換える必要があります。私が立ち往生している点は、それぞれのテーブルで置き換えている各文字列のテーブル名に言及する必要があることです

以下のようなファイルを想定

CREATE TABLE `tablename1` (
  -- #columns and keys
) ENGINE=InnoDB AUTO_INCREMENT=5075 DEFAULT CHARSET=utf8;
CREATE TABLE `tablename2` (
  -- #columns and keys
) ENGINE=something AUTO_INCREMENT=55 DEFAULT CHARSET=latin1;

望ましい結果は次のとおりです。

CREATE TABLE `tablename1` (
  -- #columns and keys
) ENGINE=-myreplacedstring/tablename1; -- #table name 1 is appended to this line
CREATE TABLE `tablename2` (
  -- #columns and keys
) ENGINE=myreplacedstring/tablename2; -- #table name 2 is appended to this line

私は試した

fin = open('dump.sql','r')
filedata = fin.read()
fin.close()

newdata = re.sub('(?<=ENGINE).*;', '-myreplacedstring-', filedata)

fout = open('fed_dump.sql','w')
fout.write(newdata)
fout.close()

ただし、これは文字列がどのテーブルであるかに関係なく、文字列を固定文字列に置き換えるだけです。

また、渡すたびにテーブル名を取得できるように行ごとにアプローチしようとしましたが、これをどのように進めるかわかりません。

 with open('dump.sql') as infile, open('dump_fed.sql', 'w') as outfile:
     for line in infile:
         #tablename= if line contains create table, update tablename, else do nothing
         line = re.sub('(?<=ENGINE).*;', '-myreplacedstring-'+tablename, line)
         outfile.write(line)

各テーブルのテーブル名を置換された文字列に取得する方法に行き詰まっています。どんな助けでも大歓迎です。

4

2 に答える 2

1

あなたのソリューションは確かに機能しますが、後方参照を使用するとより迅速に実行できます。私はこれをテストし、動作します(ワンライナーにすることもできますが、この方法の方が読みやすいです):

pattern = r"CREATE TABLE `(.*?)`(.*?)ENGINE=.*?;"
replace_pattern = r"CREATE TABLE `\1`\2ENGINE=-myreplacedstring-\1;"
newdata = re.sub(pattern, replace_pattern, filedata, flags=re.DOTALL)

と :

  • '.*' の貪欲でないバージョンである '.*?'
  • '\1' は、各オカレンスの最初のキャプチャ グループの後方参照です。たとえば、"tablename1"、"tablename2" などになります。
  • 接頭辞「r」が付いた生の文字列としてのパターン(これは良い習慣です)
  • "." を許可する re.DOTALL フラグ。改行に一致させる

次の解決策の前に提案しましたが、これは間違っています。"(?<=...)" によって通知される後読みには固定長パターンが含まれている必要があるためです。

pattern = r"(?<=CREATE TABLE `(.*?)`.*?ENGINE=).*;"
newdata = re.sub(pattern, '-myreplacedstring-\1', filedata)
于 2015-11-25T14:15:46.163 に答える
0

理解した。これがどれほどエレガントで壊れにくいかはわかりませんが、私の場合はうまくいくようです(mysql nodataダンプを取得し、エンジンをフェデレーション接続文字列に置き換えて、あるデータベースから別のデータベースへの完全なフェデレーションDBを簡単に作成します)。

import re

def gettablename(string, defaultstring):
    if 'CREATE TABLE' in string: 
        return re.search('`(.*)`', string).group(1)
    else: 
        return defaultstring

with open('dump.sql') as infile:
    tablename='def' # do i need this default?
    for line in infile:
        tablename=gettablename(line,tablename)
        line = re.sub('(?<=ENGINE).*;', '-myreplacedstring-'+tablename, line)
        print line
于 2015-11-25T14:05:57.047 に答える