Skip to content

Commit e39e7d1

Browse files
committed
reorganize
1 parent ef117fd commit e39e7d1

1 file changed

Lines changed: 164 additions & 0 deletions

File tree

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# SQLite: Handling Large Structured Data
2+
3+
## Overview
4+
Storing your data in the [SQLite](https://www.sqlite.org/index.html) format allows you to get benefits of a database, and at the same time the simplicity of storage of data in a file on a disk.
5+
6+
> SQLite is the [most used](https://www.sqlite.org/mostdeployed.html) database engine in the world. SQLite is built into all mobile phones and most computers and comes bundled inside countless other applications that people use every day. The SQLite [file format](https://www.sqlite.org/fileformat2.html) is stable, cross-platform, and backwards compatible and the developers pledge to keep it that way through at least the year 2050.
7+
>
8+
> -- [SQLite website](https://www.sqlite.org/index.html):
9+
10+
### Some use-cases
11+
12+
- You think you need MySQL, PostreSQL, etc for your ML project. Usually you don't
13+
- You have to deal with hundreds of GB of table-structured data (or larger) and your script (for whatever reason) can't be made parallel.
14+
- You would request a lot of RAM and work with data slowly.
15+
:::warning
16+
This would be a waste of RAM.
17+
:::
18+
:::tip
19+
It is better in this case to request smaller amount of RAM and read data (efficiently) from disk - for example using SQLite
20+
:::
21+
22+
### Benefits:
23+
24+
- You are not limited by RAM any longer
25+
- Compared to other file formats SQLite is very good in selecting certain lines (especially if you use indexing)
26+
- You can use familiar dplyr syntax or execute SQL queries directly
27+
- [dplyr](https://dplyr.tidyverse.org/) is an interface for working with data in a database, not for modifying remote tables.
28+
- [DBI package](https://dbi.r-dbi.org/) allows to both read and modify tables
29+
- SQLite is [actually faster for common data analysis tasks](https://www.sqlite.org/speed.html) than other popular databases.
30+
- You can have multiple threads accessing an SQLite database simultaneously (for read operations. Writing is more tricky)
31+
- Merging/Joining datasets on disk
32+
33+
### Major benefits of SQLite compared to MySQL (PostgreSQL, etc)
34+
35+
- You control your own data (sqlite file). You don't depend on any service like MySQL
36+
- You can copy a file to your own laptop and work with it
37+
- Again, [SQLite is faster](https://www.sqlite.org/speed.html)!
38+
39+
### Limits
40+
41+
- SQLite has some limitations in terms of concurrency, which usually don't apply for typical ML/AI jobs.
42+
- See [Four Different Ways To Handle SQLite Concurrency](https://medium.com/@gwendal.roue/four-different-ways-to-handle-sqlite-concurrency-db3bcc74d00e) for more information.
43+
44+
## Command line (CLI) example
45+
Create environment
46+
```sh
47+
mkdir projects/sqlite-test
48+
cd projects/sqlite-test
49+
conda create -p ./cenv
50+
conda activate ./cenv
51+
conda install -y sqlite
52+
```
53+
Then [follow this SQLite example](https://sqlite.org/cli.html).
54+
```sh
55+
sqlite3 db_file.sqlite
56+
create table tbl1(one varchar(10), two smallint);
57+
insert into tbl1 values('hello!',10);
58+
insert into tbl1 values('goodbye', 20);
59+
select * from tbl1;
60+
```
61+
Now Close session (Ctrl-D).
62+
63+
Reopen session to check if changes are saved
64+
```sh
65+
sqlite3 db_file.sqlite
66+
select * from tbl1;
67+
```
68+
69+
## R example
70+
### Install
71+
Here we use conda, as a great way to keep everything isolated and reproducible.
72+
73+
:::note
74+
conda will install pre-compiled packages. Which is good (faster) and bad (not fully optimized for a specific hardware)
75+
:::
76+
77+
:::tip
78+
Alternative: install packages to a local directory or use renv as described in [R Packages with renv](./04_r_packages_with_renv.md)
79+
```sh
80+
mkdir /scratch/$USER/projects/myTempProject
81+
cd /scratch/$USER/projects/myTempProject
82+
83+
module load anaconda3/2020.07
84+
85+
conda create -p ./cenv -c conda-forge r=4.1
86+
conda activate ./cenv
87+
conda install -c r r-rsqlite
88+
conda install -c r r-tidyverse
89+
conda install -c conda-forge r-remotes
90+
conda install -c r r-feather
91+
conda install -c r r-nycflights13
92+
```
93+
:::note
94+
95+
[window functions (row_number in particular) require newer version of rsqlite](https://github.com/r-dbi/RSQLite/issues/268)
96+
```R
97+
R
98+
remotes::install_github("r-dbi/RSQLite")
99+
## update ALL
100+
```
101+
:::
102+
:::tip
103+
Save list of installed packages for reproducibility
104+
```sh
105+
## conda list --export > requirements.txt
106+
```
107+
:::
108+
109+
### Use
110+
Many examples can be found here:
111+
- [SQL syntax](https://solutions.posit.co/connections/db/databases/sqlite/)
112+
- [dplyr syntax](https://solutions.posit.co/connections/db/r-packages/dplyr/)
113+
114+
```R
115+
library(tidyverse)
116+
library(DBI)
117+
# Create RSQLite database file with name "allData"
118+
con <- dbConnect(RSQLite::SQLite(), "allData")
119+
```
120+
121+
Copy data frame to database (dplyr)
122+
```R
123+
copy_to(con, nycflights13::flights, "fl", temporary=FALSE)
124+
```
125+
126+
Or copy data to database using DBI
127+
```R
128+
dbCreateTable(con, "fl", nycflights13::flights, temporary = FALSE)
129+
dbAppendTable(con, "fl", nycflights13::flights)
130+
```
131+
132+
Connect to a specific table
133+
```R
134+
dbListTables(con)
135+
df_con <- tbl(con, "fl")
136+
## check number of rows
137+
df_con %>% count()
138+
```
139+
140+
Subset
141+
```R
142+
df_temp <- df_con %>% filter( row_number() %in% c(1, 3) ) %>% collect
143+
```
144+
145+
Save as feather
146+
```R
147+
feather::write_feather(df_temp, paste0("file_", ind, ".feather"))
148+
```
149+
150+
### Alternative: read csv file to SQLite directly
151+
152+
If you already have a large csv file on disk, and you don't want to read it to RAM, you can read it to SQLite file directly
153+
```R
154+
conda install -c conda-forge r-sqldf
155+
R
156+
library(sqldf)
157+
## create data file
158+
sqldf("attach allData as new")
159+
## read file directly from csv to sqlite
160+
read.csv.sql(file = "test.tab", sql = "create table states_data as select * from file", dbname = "allData")
161+
```
162+
163+
## UI for SQLite - SQLiteStudio
164+
Once you have SQLite file, you can easily transfer it to your own laptop and explore it using [SQLiteStudio](https://sqlitestudio.pl/), if you like to use UI instead of terminal

0 commit comments

Comments
 (0)