I found this Perl script while migrating my SQLite database to mysql
I was wondering (since I don\'t know Perl) how could one rewrite this in Python?
Bonus point
Here's a pretty literal translation with just the minimum of obvious style changes (putting all code into a function, using string rather than re operations where possible).
import re, fileinput
def main():
for line in fileinput.input():
process = False
for nope in ('BEGIN TRANSACTION','COMMIT',
'sqlite_sequence','CREATE UNIQUE INDEX'):
if nope in line: break
else:
process = True
if not process: continue
m = re.search('CREATE TABLE "([a-z_]*)"(.*)', line)
if m:
name, sub = m.groups()
line = '''DROP TABLE IF EXISTS %(name)s;
CREATE TABLE IF NOT EXISTS %(name)s%(sub)s
'''
line = line % dict(name=name, sub=sub)
else:
m = re.search('INSERT INTO "([a-z_]*)"(.*)', line)
if m:
line = 'INSERT INTO %s%s\n' % m.groups()
line = line.replace('"', r'\"')
line = line.replace('"', "'")
line = re.sub(r"([^'])'t'(.)", r"\1THIS_IS_TRUE\2", line)
line = line.replace('THIS_IS_TRUE', '1')
line = re.sub(r"([^'])'f'(.)", r"\1THIS_IS_FALSE\2", line)
line = line.replace('THIS_IS_FALSE', '0')
line = line.replace('AUTOINCREMENT', 'AUTO_INCREMENT')
print line,
main()
all of scripts on this page can't deal with simple sqlite3:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE Filename (
FilenameId INTEGER,
Name TEXT DEFAULT '',
PRIMARY KEY(FilenameId)
);
INSERT INTO "Filename" VALUES(1,'');
INSERT INTO "Filename" VALUES(2,'bigfile1');
INSERT INTO "Filename" VALUES(3,'%gconf-tree.xml');
None were able to reformat "table_name" into proper mysql's `table_name` . Some messed up empty string value.
Based on http://docs.python.org/dev/howto/regex.html ...
$line =~ /.*/
with re.search(r".*", line)
.$line !~ /.*/
is just !($line =~ /.*/)
.$line =~ s/.*/x/g
with line=re.sub(r".*", "x", line)
.$1
through $9
inside re.sub
with \1
through \9
respectively.m=re.search()
, and replace $1
with the return value of m.group(1)
."INSERT INTO $1$2\n"
specifically, you can do "INSERT INTO %s%s\n" % (m.group(1), m.group(2))
.Real issue is do you know actually how to migrate the database? What is presented is merely a search and replace loop.
Here is a slightly better version of the original.
#! /usr/bin/perl
use strict;
use warnings;
use 5.010; # for s/\K//;
while( <> ){
next if m'
BEGIN TRANSACTION |
COMMIT |
sqlite_sequence |
CREATE UNIQUE INDEX
'x;
if( my($name,$sub) = m'CREATE TABLE \"([a-z_]*)\"(.*)' ){
# remove "
$sub =~ s/\"//g; #"
$_ = "DROP TABLE IF EXISTS $name;\nCREATE TABLE IF NOT EXISTS $name$sub\n";
}elsif( /INSERT INTO \"([a-z_]*)\"(.*)/ ){
$_ = "INSERT INTO $1$2\n";
# " => \"
s/\"/\\\"/g; #"
# " => '
s/\"/\'/g; #"
}else{
# '' => \'
s/\'\'/\\\'/g; #'
}
# 't' => 1
s/[^\\']\K\'t\'/1/g; #'
# 'f' => 0
s/[^\\']\K\'f\'/0/g; #'
s/AUTOINCREMENT/AUTO_INCREMENT/g;
print;
}
I am not sure what is so hard to understand about this that it requires a snide remark as in your comment above. Note that <>
is called the diamond operator. s///
is the substitution operator and //
is the match operator m//
.