回答

收藏

将MySQL转储导入R(不需要MySQL服务器)

技术问答 技术问答 113 人阅读 | 0 人回复 | 2023-09-13

像包RMySQL,并sqldf允许一个与本地或远程数据库服务器连接。我创建一个便携式项目,该项目涉及的情况下导入SQL数据(或设备)不总是可以访问正在运行的服务器,但/ y' s* Y- h8 ~6 }
你 总是可以访问数据库的最新.SQL转储。
# K! Q' c& o# \' ~0 m- l, ~目标似乎很简单:在不涉及MySQL服务器的情况下将.sql转储导入R。
, F5 K/ k  i( W6 C4 ^, d% Q更具体地说,我想创建一个列表列表,其中的元素与.sql转储中定义的任何数据库相对应(可能有多个),而这些元素又由这些数据库中的表组成。
( q2 [" D' n# F( x* y4 K为了重现这一点,让我们在此处获取样本sportsdb8 F  O+ Y: z2 x$ a1 N4 B
SQL文件-如果将其解压缩,则称为sportsdb_sample_mysql_20080303.sql。0 n2 b7 T6 ?  }# F
有人会认为sqldf可以做到这一点:
2 p6 o8 ~- [! p  |. ^8 F1 b6 B! zread.csv.sql('sportsdb_sample_mysql_20080303.sql', sql="SELECT * FROM
' t1 [0 n9 b! W7 a, ]1 d0 E! K  g6 ~addresses") Error in sqliteSendQuery(con, statement, bind.data) : error in
- M, s0 y* y, V: c& D3 q5 fstatement: no such table: addresses, x3 _. l6 k1 ^) a
即使在转储中肯定有一个表地址也是如此。sqldf列表上的该帖子提到了相同的错误,但没有解决方案。5 z% L; p/ L! Q8 b4 O" X8 t
然后sql.reader,软件包中有一个函数ProjectTemplate,看起来很有希望。随便看看,该功能的源代码可以在这里找到,它假设一个正在运行的数据库服务器并依赖于RMySQL…而不是我所需要的。
: }/ m$ b9 |+ {: O所以…我们似乎用光了所有的选项。蜂巢的任何帮助表示赞赏!
* o8 S7 ?' z( W(再次重申,我 不是
- `1 v! y  h- G' t找依靠进入到SQL服务器的解决方案;与很容易dbReadTable从RMySQL,包我非常想绕过服务器,并从.SQL转储文件直接获取数据。)
& g; H0 ~( v5 M: d3 y0 j9 g" c  O               
! q0 i, D8 E4 j5 @解决方案:. h+ I! Z9 o1 N- h3 K; c
                4 [8 t  |% K) u  \3 P1 m8 v

5 d- j  j8 U- @
% ^" b2 p! Z! C                根据要从表中提取的内容,这是如何处理数据的方法% }3 F% {! O* I6 R& `# L' j
numLines 然后,您可以执行一些正则表达式来获取表名(在CREATE TABLE之后),列名(在第一括号之间)和VALUES(在CREATE
' x; }$ `" m% u3 E! N+ hTABLE之后和第二括号之间的行)+ X' R( @) H7 ]! z( W0 V& }
) |, |6 u' |5 i: o- r- B
编辑:响应OP的回答,如果我正确解释python脚本,它也将逐行读取它,过滤INSERT" M6 c) ^, D/ f; ~) a& P/ T
INTO行,解析为csv,然后写入文件。这与我最初的建议非常相似。我的版本在R中。如果文件太大,最好使用一些其他R包以大块形式读取文件% D6 P+ A" F0 [( f6 B
options(stringsAsFactors=F)
6 J$ Q: L# T% wlibrary(utils)
7 I% R4 l$ h* N- Y% elibrary(stringi)2 E! t( b8 D. K8 b) q) n, [4 |
library(plyr)
5 Y- D" \: k1 o0 I4 J- ymysqldumpfile <- &quot;sportsdb_sample_mysql_20080303.sql&quot;
) R/ n3 I; j& [: r+ L: hallLines <- readLines(mysqldumpfile)
0 e4 h- N# g# {! p& binsertLines <- allLines[which(stri_detect_fixed(allLines, &quot;INSERT INTO&quot;))]( Z. `, W: v4 Z
allwords <- data.frame(stri_extract_all_words(insertLines, &quot; &quot;))
" n5 ~% e; _; P8 ~: w; {d_ply(allwords, .(X3), function(x) {# R" ^  X5 P' q' C: W4 b& }
    #x <- split(allwords, allwords$X3)[[&quot;baseball_offensive_stats&quot;]]3 C% R; g8 L9 u9 \' ~7 H
    print(x[1,3])$ x& P  Q9 H6 [9 v& _/ m8 K; B
    #find where the header/data columns start and end
. O: @7 i+ S! O% C    valuesCol <- which(x[1,]==&quot;VALUES&quot;)
' z/ p: }% t: z1 M* m    lastCols <- which(apply(x, 2, function(y) all(is.na(y))))
. C( p" ^; V) Z6 \    datLastCol <- head(c(lastCols, ncol(x)+1), 1) - 1
+ O6 I, P/ v- f( R5 X" U    #format and prepare for write to file
8 G* `' K3 Y+ ^& L0 d( K    df <- data.frame(x[,(valuesCol+1):datLastCol])1 e; G+ Y) l' o2 n7 G2 n
    df <- setNames(df, x[1,4valuesCol-1)])
) {" H! m* m; ~5 x- c. v    #type convert before writing to file otherwise its all strings9 T" J+ X8 A# H0 [: i. ]) z8 U
    df[] <- apply(df, 2, type.convert)- J. ~1 A, F/ m4 I0 C
    #write to file) k5 [# M, U/ U# q/ R# \% K' t
    write.csv(df, paste0(x[1,3],&quot;.csv&quot;), row.names=F)
7 F1 N; ]) h% _- n: y$ Y})
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则