arql 0.4.0 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.vscode/launch.json +1 -1
- data/Gemfile.lock +1 -1
- data/README-zh_CN.org +10 -162
- data/README.org +803 -628
- data/auto-set-id-before-save.org +1 -1
- data/custom-configurations.org +71 -32
- data/define-associations.org +52 -29
- data/initializer-structure-zh_CN.org +1 -1
- data/initializer-structure.org +46 -18
- data/lib/arql/cli.rb +6 -0
- data/lib/arql/definition.rb +1 -1
- data/lib/arql/repl.rb +1 -1
- data/lib/arql/version.rb +1 -1
- data/oss-files-zh_CN.org +2 -2
- data/oss-files.org +2 -2
- data/sql-log.org +8 -3
- metadata +2 -2
data/README.org
CHANGED
@@ -2,39 +2,39 @@
|
|
2
2
|
|
3
3
|
[[./README-zh_CN.org][中文]]
|
4
4
|
|
5
|
-
Arql is a simple
|
6
|
-
automatically define model classes based on database
|
7
|
-
as your database query tool.
|
8
|
-
|
9
|
-
**
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
- MySQL: Depending on your operating system, you may need to install: =libmariadb-dev
|
14
|
-
=default-libmysqlclient-dev= ;
|
15
|
-
|
16
|
-
-
|
17
|
-
-
|
18
|
-
-
|
5
|
+
Arql is a simple instrumental gem that combines Rails ActiveRecord and Pry, and adds useful Pry commands. It can
|
6
|
+
automatically define model classes based on information from database tables. If you're a Ruby user, you can use this
|
7
|
+
Arql as your database query tool.
|
8
|
+
|
9
|
+
** Dependencies
|
10
|
+
|
11
|
+
- Ruby 2.6.0 or later
|
12
|
+
- For different types of databases, you need to install the appropriate database adapter or client binary library:
|
13
|
+
- MySQL: Depending on your operating system, you may need to install: , =libmariadb-dev= =libmysqlclient-dev=
|
14
|
+
=mysql-devel= , =default-libmysqlclient-dev= ; Refer to your distribution's package guide to find your specific
|
15
|
+
package, or refer to the mysql2 documentation
|
16
|
+
- SQLite3: No need to install any additional libraries
|
17
|
+
- PostgreSQL: =gem install pg=
|
18
|
+
- Oracle: =gem install activerecord-oracle_enhanced-adapter=
|
19
|
+
- SQL Server: =gem install activerecord-sqlserver-adapter=
|
19
20
|
|
20
21
|
** Installation
|
21
|
-
|
22
|
-
|
22
|
+
|
23
|
+
Execute:
|
23
24
|
|
24
25
|
#+begin_example
|
25
26
|
$ gem install arql
|
26
27
|
#+end_example
|
27
28
|
|
28
|
-
|
29
|
+
If you're having problems with system permissions, try using sudo:
|
29
30
|
|
30
31
|
#+begin_example
|
31
32
|
$ sudo gem install arql
|
32
33
|
#+end_example
|
33
34
|
|
34
|
-
**
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
** How to Use
|
36
|
+
*** Command Line Options
|
37
|
+
|
38
38
|
#+begin_example
|
39
39
|
Usage: arql [options] [ruby file]
|
40
40
|
|
@@ -67,41 +67,73 @@
|
|
67
67
|
|
68
68
|
**** =-c, --config=CONFIG_FILE=
|
69
69
|
|
70
|
-
Specify the
|
71
|
-
|
72
|
-
=ssh=
|
70
|
+
Specify the profile location, which defaults to =$HOME/.arql.yml= or =$HOME/.arql.d/init.yml= . Configuration files are
|
71
|
+
usually the same as Rails database configuration files, but there are some additional configuration options, such as
|
72
|
+
=ssh= options, etc. References =Configuration Files= section.
|
73
73
|
|
74
74
|
**** =-i, --initializer=INITIALIZER=
|
75
75
|
|
76
|
-
Specify a Ruby source file
|
77
|
-
=$HOME/.arql.rb= or =$HOME/.arql.d/init.rb
|
78
|
-
|
79
|
-
|
76
|
+
Specify a Ruby source file and execute the code for Arql after defining the ActiveRecord model class, which defaults to
|
77
|
+
=$HOME/.arql.rb= or =$HOME/.arql.d/init.rb= . In this file, you can add method and association definitions to the
|
78
|
+
ActiveRecord model class.
|
79
|
+
|
80
80
|
**** =-e, --env=ENVIRON=
|
81
81
|
|
82
|
-
Specify
|
82
|
+
Specify one or more environment names in the configuration file, separated by commas/pluses/colons.
|
83
|
+
|
84
|
+
The model classes that Arql generates for each environment will be placed in the namespace specified by the =namespace=
|
85
|
+
configuration for that environment. For example:
|
86
|
+
|
87
|
+
#+BEGIN_SRC yaml
|
88
|
+
development:
|
89
|
+
adapter: mysql2
|
90
|
+
host: localhost
|
91
|
+
username: root
|
92
|
+
database: myapp_development
|
93
|
+
pool: 5
|
94
|
+
namespace: Dev
|
95
|
+
#+END_SRC
|
96
|
+
|
97
|
+
Suppose there is a table in the =myapp_development= database named =users= , =posts= etc., then the model class
|
98
|
+
generated in the =development= environment will be:
|
99
|
+
|
100
|
+
- =Dev::User=
|
101
|
+
- =Dev::Post=
|
102
|
+
|
103
|
+
If no =namespace= configuration is specified, the default namespace is in the form of CamelCase for the environment
|
104
|
+
name. For example =Development= , here , then the resulting model class would be:
|
105
|
+
|
106
|
+
- =Development::User=
|
107
|
+
- =Development::Post=
|
108
|
+
|
109
|
+
Arql =Object.const_missing= also defines an "alias" under the top-level namespace for those model classes whose class
|
110
|
+
names and existing constants do not have the same name, for example, if the class name is not the same as the existing
|
111
|
+
constant name, it can be directly used =User= . =Post=
|
112
|
+
|
113
|
+
If there are tables with the same names in more than one environment, an alias will be defined for the model classes of
|
114
|
+
the tables in the previous environments in the order of the specified environments
|
83
115
|
|
84
116
|
**** =-E, --eval=CODE=
|
85
117
|
|
86
|
-
Specify a Ruby
|
118
|
+
Specify a Ruby snippet, if specified, the Pry REPL will not be launched.
|
87
119
|
|
88
120
|
**** =-S, --show-sql=
|
89
121
|
|
90
|
-
arql does not display SQL logs by default
|
122
|
+
arql does not display SQL logs by default and is turned on with this option.
|
91
123
|
|
92
124
|
**** =-w, --write-sql=OUTPUT=
|
93
125
|
|
94
|
-
You can also use this option to
|
126
|
+
You can also use this option to have arql write SQL logs to a file.
|
95
127
|
|
96
128
|
**** =-A, --append-sql-OUTOUT=
|
97
129
|
|
98
|
-
Similar to
|
130
|
+
=-w= Similar to , but with append writes, existing files are not truncated.
|
99
131
|
|
100
132
|
**** Database options
|
101
133
|
|
102
|
-
The options described in this section are
|
103
|
-
|
104
|
-
modified in the CLI.
|
134
|
+
The options described in this section are typically configured in a configuration file, and these options are
|
135
|
+
simply shortcuts to the configuration items in the configuration file so that certain configuration items can be
|
136
|
+
modified directly in the CLI.
|
105
137
|
|
106
138
|
***** -a, --db-adapter=DB_ADAPTER
|
107
139
|
|
@@ -127,7 +159,7 @@
|
|
127
159
|
|
128
160
|
***** -u, --db-user=DB_USER
|
129
161
|
|
130
|
-
Specify the database
|
162
|
+
Specify the database user
|
131
163
|
|
132
164
|
***** -P, --db-password=DB_PASSWORD
|
133
165
|
|
@@ -135,7 +167,7 @@
|
|
135
167
|
|
136
168
|
***** -n, --db-encoding=DB_ENCODING
|
137
169
|
|
138
|
-
Specify the database
|
170
|
+
Specify the database encoding, default is =utf8=
|
139
171
|
|
140
172
|
***** -o, --db-pool=DB_POOL
|
141
173
|
|
@@ -143,8 +175,8 @@
|
|
143
175
|
|
144
176
|
***** -H, --ssh-host=SSH_HOST
|
145
177
|
|
146
|
-
Specify the SSH host, when the SSH
|
147
|
-
|
178
|
+
Specify the SSH host, when the SSH-related options are specified, arql will establish an SSH tunnel and connect to
|
179
|
+
the
|
148
180
|
|
149
181
|
***** -O, --ssh-port=SSH_PORT
|
150
182
|
|
@@ -152,7 +184,7 @@
|
|
152
184
|
|
153
185
|
***** -U, --ssh-user=SSH_USER
|
154
186
|
|
155
|
-
Specify the SSH
|
187
|
+
Specify the SSH user
|
156
188
|
|
157
189
|
***** -W, --ssh-password=SSH_PASSWORD
|
158
190
|
|
@@ -160,24 +192,57 @@
|
|
160
192
|
|
161
193
|
***** -L, --ssh-local-port=SSH_LOCAL_PORT
|
162
194
|
|
163
|
-
Specify the
|
195
|
+
Specify the local SSH proxy port
|
164
196
|
|
165
|
-
*** Configuration
|
197
|
+
*** Configuration Files
|
166
198
|
|
167
|
-
The path
|
168
|
-
usually the same as the Rails database configuration file, but there are some additional configuration options:
|
199
|
+
The path to the configuration file defaults to or =$HOME/.arql.yml= =$HOME/.arql.d/init.yml= . The configuration file
|
200
|
+
is usually the same as the Rails database configuration file, but there are some additional configuration options:
|
169
201
|
|
170
|
-
1. =created_at= : An array of custom column names containing the ActiveRecord =created_at= field,
|
171
|
-
|
172
|
-
|
202
|
+
1. =created_at= : An array of custom column names containing the ActiveRecord =created_at= field, with the default value
|
203
|
+
of , if specified =created_at= , the value of the column will be populated with the current timestamp when created
|
204
|
+
2. =updated_at= : An array of custom column names containing the ActiveRecord =updated_at= field, with the default value
|
205
|
+
of , if specified =updated_at= , the value of the column will be populated with the current timestamp when updated
|
206
|
+
3. =ssh.host= : ssh host, you can use the hostname in the =ssh_config= file, or it can be a direct IP address or
|
207
|
+
hostname
|
173
208
|
4. =ssh.port= : ssh port, default is =22=
|
174
|
-
5.
|
175
|
-
6.
|
176
|
-
7.
|
177
|
-
8. =singularized_table_names
|
178
|
-
|
209
|
+
5. =ssh.user= : ssh username
|
210
|
+
6. =ssh.password= : SSH password
|
211
|
+
7. =ssh.local_port= : ssh local port
|
212
|
+
8. =singularized_table_names= : Whether to use the singular table name, the default is =false= , if it is =false= , the
|
213
|
+
=students= table will be defined as a =Student= model, if it is =true= , the =students= table will be defined as a
|
214
|
+
=Students= model
|
215
|
+
9. =table_name_prefixes= : An array of table name prefixes, which default is an empty array, if specified, these
|
216
|
+
prefixes will be ignored when generating the model, for example =["t_"]= , if , the =t_students= table will be
|
217
|
+
defined as a =Student= model
|
218
|
+
10. =namespace= : The model namespace, which defaults to the CamelCase form of the environment name, and the generated
|
219
|
+
model will be placed under the specified namespace
|
220
|
+
11. =model_names= : The value of this configuration item is a hash(map), the key is the table name, and the value is the
|
221
|
+
name of the model to be generated for the table. Arql uses ActiveRecord's naming convention to generate model names
|
222
|
+
by default, and if this configuration item is specified, the table specified by the configuration item will use the
|
223
|
+
model name specified by the modified configuration itemValue can be an array of strings in addition to a string
|
224
|
+
representing the model name, with the first element of the array representing the model name and the second element
|
225
|
+
representing the constant alias (Arql) created for the model By default, aliases are also automatically created for
|
226
|
+
the generated model class according to certain rules, and if an alias is specified here, the user-provided value
|
227
|
+
will be used as the alias)
|
228
|
+
|
229
|
+
=model_names= Examples of configuration items:
|
230
|
+
|
231
|
+
#+BEGIN_SRC yaml
|
232
|
+
development:
|
233
|
+
host: localhost
|
234
|
+
database: test
|
235
|
+
username: root
|
236
|
+
model_names:
|
237
|
+
students: Seito
|
238
|
+
teachers: ["LaoShi", "LS"]
|
239
|
+
#+END_SRC
|
179
240
|
|
180
|
-
|
241
|
+
In the above configuration file, a model named for the =students= table will be generated, a model named =LaoShi= for
|
242
|
+
the =teachers= table will be generated for the table, and a constant alias named =LS= will be created for the =LaoShi=
|
243
|
+
model. An alias is also generated for the =students= table: =S=
|
244
|
+
|
245
|
+
**** Example configuration file
|
181
246
|
|
182
247
|
#+begin_example
|
183
248
|
default: &default
|
@@ -191,9 +256,10 @@
|
|
191
256
|
<<: *default
|
192
257
|
username: root
|
193
258
|
database: blog
|
194
|
-
table_name_prefixes: ["t_"]
|
195
259
|
password:
|
260
|
+
table_name_prefixes: ["t_"]
|
196
261
|
socket: /tmp/mysql.sock
|
262
|
+
namespace: B
|
197
263
|
|
198
264
|
dev:
|
199
265
|
<<: *default
|
@@ -203,6 +269,7 @@
|
|
203
269
|
password: 123456
|
204
270
|
database: blog
|
205
271
|
table_name_prefixes: ["t_"]
|
272
|
+
namespace: B
|
206
273
|
ssh:
|
207
274
|
host: dev.mycompany.com
|
208
275
|
port: 22
|
@@ -211,35 +278,34 @@
|
|
211
278
|
local_port: 3307
|
212
279
|
#+end_example
|
213
280
|
|
281
|
+
In the example =default= , a generic configuration item is defined, as well as two specific database environments
|
282
|
+
=local= and =dev= . =local= =dev= =<<: *default= and inherit =default= the configuration items of .
|
214
283
|
|
215
|
-
|
216
|
-
|
217
|
-
|
284
|
+
=arql -e dev= When the command is executed, arql uses the =dev= configuration in the configuration file; =arql -e local=
|
285
|
+
When the command is executed, arql uses the =local= configuration in the configuration file.
|
218
286
|
|
219
|
-
|
220
|
-
|
287
|
+
=dev= The environment uses an SSH tunnel, and when you connect to a =devdb.mycompany.com= database, you will first
|
288
|
+
establish an SSH tunnel to and then connect to =dev.mycompany.com= the database through the SSH tunnel.
|
221
289
|
|
290
|
+
*** Use as a REPL
|
222
291
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
*** Use Arql as REPL
|
227
|
-
|
228
|
-
If neither =[ruby file]= nor the =-E= option is specified, and STDIN is a =tty=, arql will start a Pry REPL. For example, execute:
|
292
|
+
If neither the =[ruby file]= Nor the Specify =-E= option is specified, and the STDIN is a =tty= , arql launches a Pry
|
293
|
+
REPL. For example, execute:
|
229
294
|
|
230
295
|
#+BEGIN_EXAMPLE
|
231
296
|
arql -e dev
|
232
297
|
#+END_EXAMPLE
|
233
298
|
|
234
299
|
|
235
|
-
Arql provides
|
300
|
+
Arql provides a few Pry commands:
|
301
|
+
|
236
302
|
|
237
303
|
**** =info=
|
238
304
|
|
239
|
-
|
305
|
+
=info= The command prints the current database connection information and SSH proxy information, for example:
|
240
306
|
|
241
307
|
#+begin_example
|
242
|
-
Database Connection Information:
|
308
|
+
my_env Database Connection Information:
|
243
309
|
Host:
|
244
310
|
Port:
|
245
311
|
Username: root
|
@@ -250,96 +316,66 @@
|
|
250
316
|
Pool Size: 5
|
251
317
|
#+end_example
|
252
318
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
#+
|
258
|
-
|
259
|
-
|
260
|
-
+--------------------+------------------+------+----------------+
|
261
|
-
| post | Post | P | Posts |
|
262
|
-
| org | Org | O | Orginations |
|
263
|
-
| user_org | UserOrg | UO | |
|
264
|
-
| student | Student | S | Students |
|
265
|
-
| course | Course | C | |
|
266
|
-
| score | Score | S2 | |
|
267
|
-
| users | Users | U | |
|
268
|
-
| posts | Posts | P2 | |
|
269
|
-
| authors | Authors | A | |
|
270
|
-
+--------------------+------------------+------+----------------+
|
271
|
-
#+end_example
|
272
|
-
|
273
|
-
Where:
|
274
|
-
|
275
|
-
- =Table Name= : Table name
|
276
|
-
- =Model Class= : Model class name
|
277
|
-
- =Abbr= : Abbreviated class name
|
278
|
-
- =Comment= : Comment
|
279
|
-
|
280
|
-
The =m= / =l= command can also accept a parameter to filter the list by table name or table comment, for example:
|
281
|
-
|
282
|
-
=m perm= will only list tables that contain =perm= in the table name or table comment; if you want to use regular expressions to match,
|
283
|
-
you can use =m /perm/i= to match.
|
284
|
-
|
285
|
-
**** =t=
|
319
|
+
=info= By default, the connection information for all specified environments is displayed, if you only want to display
|
320
|
+
the connection information of the current environment, the =info= command accepts a regular expression argument and only
|
321
|
+
displays the matching environment information, for example:
|
322
|
+
|
323
|
+
#+BEGIN_EXAMPLE
|
324
|
+
info .*dev
|
325
|
+
#+END_EXAMPLE
|
286
326
|
|
287
|
-
|
327
|
+
**** =m= or =l=
|
288
328
|
|
289
|
-
|
329
|
+
=m= (or =l= ) command to print all table names and corresponding model class names and abbreviated class names, for
|
330
|
+
example:
|
290
331
|
|
291
332
|
#+begin_example
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
333
|
+
+--------------------+------------------+------+---------+
|
334
|
+
| Table Name | Model Class | Abbr | Comment |
|
335
|
+
+--------------------+------------------+------+---------+
|
336
|
+
| post | Post | P | 帖子 |
|
337
|
+
| org | Org | O | 组织 |
|
338
|
+
| user_org | UserOrg | UO | |
|
339
|
+
| student | Student | S | 学生 |
|
340
|
+
| course | Course | C | |
|
341
|
+
| score | Score | S2 | |
|
342
|
+
| users | Users | U | |
|
343
|
+
| posts | Posts | P2 | |
|
344
|
+
| authors | Authors | A | |
|
345
|
+
+--------------------+------------------+------+---------+
|
303
346
|
#+end_example
|
304
347
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
Where:
|
309
|
-
|
310
|
-
- =PK= : Whether it is a primary key
|
311
|
-
- =Name= : Column name
|
312
|
-
- =SQL Type= : Database type
|
313
|
-
- =Ruby Type= : Ruby type
|
314
|
-
- =Limit= : Length limit
|
315
|
-
- =Precision= : Precision
|
316
|
-
- =Scale= : Number of decimal places
|
317
|
-
- =Default= : Default value
|
318
|
-
- =Nullable= : Whether it can be empty
|
319
|
-
- =Comment= : Comment
|
320
|
-
|
321
|
-
**** =vd=
|
348
|
+
Thereinto:
|
322
349
|
|
350
|
+
- =Table Name= : Table name
|
351
|
+
- =Model Class= : Model class name
|
352
|
+
- =Abbr= : Abbreviated class name
|
353
|
+
- =Comment= :Exegesis.
|
323
354
|
|
324
|
-
|
325
|
-
is that if the number of columns in the table is too large, it will cause the table to wrap, which is not
|
326
|
-
convenient to view. =vd= (visidata) is a terminal data analysis tool written in Python, which can print the table
|
327
|
-
definition information in the terminal in the form of a table, but supports horizontal scrolling, which is
|
328
|
-
convenient for viewing.
|
355
|
+
=m= / =l= Command with three optional options:
|
329
356
|
|
330
|
-
|
357
|
+
- =-e= , =--env= : Specify the environment, regular expression, only display the table name in the matching environment,
|
358
|
+
and display all environments by default
|
359
|
+
- =-f= , =--format= : Output Format:
|
360
|
+
- =terminal= : Default table format
|
361
|
+
- =md= : markdown table format
|
362
|
+
- =org= : org mode table format
|
363
|
+
- =sql= : 输出 create table SQL
|
364
|
+
- =-c= , =--column= : Regular expression, which lists fields, not tables, and filters by field name or field comment
|
331
365
|
|
332
|
-
|
333
|
-
|
334
|
-
#+end_src
|
366
|
+
=m= The / =l= command can also accept an optional regular expression argument that displays only information about
|
367
|
+
matching tables (by table name or table comment), for example:
|
335
368
|
|
336
|
-
|
337
|
-
|
338
|
-
|
369
|
+
#+BEGIN_EXAMPLE
|
370
|
+
l # Print all table information
|
371
|
+
l ^post # Only display information about tables whose names start with post
|
372
|
+
l -e dev -f md # Display table information in the dev environment and output in markdown format
|
373
|
+
l -c no|num # Display only field information containing no or num in field name or field comment
|
374
|
+
#+END_EXAMPLE
|
339
375
|
|
340
376
|
**** =show-sql= / =hide-sql=
|
341
377
|
|
342
|
-
This pair of commands
|
378
|
+
This pair of commands toggles the display of SQL logs in the Pry REPL.
|
343
379
|
|
344
380
|
By default, SQL logs are not displayed:
|
345
381
|
|
@@ -348,7 +384,7 @@
|
|
348
384
|
=> 0
|
349
385
|
#+end_example
|
350
386
|
|
351
|
-
|
387
|
+
When you open the SQL log, you will see the SQL statement that was executed each time:
|
352
388
|
|
353
389
|
#+begin_example
|
354
390
|
ARQL@demo247(main) [3] ❯ show-sql
|
@@ -359,61 +395,54 @@
|
|
359
395
|
|
360
396
|
**** =reconnect=
|
361
397
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
398
|
+
=reconnect= The command is used to reconnect the current database connection. When the connection is lost due to network
|
399
|
+
reasons, you can use the command to reconnect. reconnect, the objects in the current Pry session are not lost.
|
400
|
+
=reconnect= First, it will determine whether the current connection is still valid, if it is valid, it will not be
|
401
|
+
reconnected, if =reconnect= the validity of the connection is wrong, you can use =reconnect!= the command to force a
|
402
|
+
reconnection.
|
367
403
|
|
368
404
|
**** =redefine=
|
369
|
-
The =redefine= command is used to redefine the ActiveRecord model class and regenerate the model class based on
|
370
|
-
the information of the database table. If you have added new relationship definitions in =init.rb= and want the
|
371
|
-
new definitions to take effect in the current Pry session, you can use the =redefine= command.
|
372
405
|
|
373
|
-
|
406
|
+
=redefine= The command is used to redefine the ActiveRecord model class, which regenerates the model class based on the
|
407
|
+
information from the database table. =init.rb= If you want a new relationship definition to take effect in the current
|
408
|
+
Pry session, you can use =redefine= the command.
|
374
409
|
|
375
|
-
|
376
|
-
|
410
|
+
**** =sandbox-enter= 和 =sandbox-quit=
|
411
|
+
|
412
|
+
=sandbox-enter= command to turn on sandbox mode. In sandbox mode, all database operations are executed in a
|
413
|
+
transaction, which is not automatically committed, and is automatically rolled back when exiting sandbox mode.
|
414
|
+
|
415
|
+
1. Turn on sandbox mode:
|
377
416
|
|
378
|
-
1. Enter sandbox mode:
|
379
|
-
#+begin_example
|
380
|
-
ARQL@demo247(main) [6] ❯ sandbox-enter
|
381
|
-
ARQL@demo247 [sandbox] (main) [7] ❯
|
382
|
-
#+end_example
|
383
|
-
2. Quit sandbox mode:
|
384
|
-
#+begin_example
|
385
|
-
ARQL@demo247 [sandbox] (main) [7] ❯ sandbox-quit
|
386
|
-
begin_transaction callbacks removed.
|
387
|
-
You still have open 1 transactions open, don't forget commit or rollback them.
|
388
|
-
#+end_example
|
389
|
-
3. Commit the transaction:
|
390
417
|
#+begin_example
|
391
|
-
|
418
|
+
ARQL@demo247(main) [6] ❯ sandbox-enter
|
419
|
+
ARQL@demo247 [sandbox] (main) [7] ❯
|
392
420
|
#+end_example
|
393
|
-
|
421
|
+
|
422
|
+
2. To exit sandbox mode:
|
423
|
+
|
394
424
|
#+begin_example
|
395
|
-
|
425
|
+
ARQL@demo247 [sandbox] (main) [7] ❯ sandbox-quit
|
396
426
|
#+end_example
|
397
427
|
|
398
|
-
*** Use
|
428
|
+
*** Use as a Code Interpreter
|
399
429
|
|
430
|
+
If a Ruby file is specified as a command-line argument, or if the option is used =-E= , or if STDIN is not a =tty= ,
|
431
|
+
then Arql will not start Pry, but will simply execute the specified file or code snippet (or read code from standard
|
432
|
+
input). The model class definition is loaded before the code snippet is executed. You can think of this usage as
|
433
|
+
something like a =runner= subcommand =rails= of .
|
400
434
|
|
401
|
-
|
402
|
-
will not start Pry, but will directly execute the specified file or code snippet (or read code from standard
|
403
|
-
input). Before executing the code snippet, the model class definition will be loaded first. You can think of this
|
404
|
-
usage as similar to the =runner= subcommand of =rails=.
|
435
|
+
**** Use =-E= the option
|
405
436
|
|
406
|
-
|
407
|
-
|
408
|
-
The =-E= option can be used to execute code snippets directly without starting Pry:
|
437
|
+
The =-E= option allows you to execute the code snippet directly without starting Pry:
|
409
438
|
|
410
439
|
#+begin_example
|
411
440
|
$ arql -e dev -E 'puts Person.count'
|
412
441
|
#+end_example
|
413
442
|
|
414
|
-
****
|
443
|
+
**** Specify a Ruby file as a command-line argument
|
415
444
|
|
416
|
-
By specifying a Ruby file as a command-line
|
445
|
+
By specifying a Ruby file as a command-line argument, you can execute code directly from a Ruby file:
|
417
446
|
|
418
447
|
=test.rb=:
|
419
448
|
|
@@ -425,34 +454,88 @@
|
|
425
454
|
$ arql -e dev test.rb
|
426
455
|
#+end_example
|
427
456
|
|
428
|
-
**** Read code from standard input
|
457
|
+
**** Read the code from the standard input
|
429
458
|
|
430
|
-
Reading code from standard input,
|
459
|
+
Reading code from standard input, the code snippet can be executed directly:
|
431
460
|
|
432
461
|
#+begin_example
|
433
462
|
$ echo 'puts Person.count' | arql -e dev
|
434
463
|
#+end_example
|
435
464
|
|
436
|
-
|
437
|
-
|
465
|
+
** Additional Extension Methods
|
466
|
+
*** Module Methods for Namespace Modules
|
467
|
+
**** =q=
|
468
|
+
|
469
|
+
=q= Used to execute SQL queries
|
470
|
+
|
471
|
+
#+begin_example
|
472
|
+
ARQL ❯ rs = Blog::q 'select count(0) from person;'
|
473
|
+
=> #<ActiveRecord::Result:0x00007fd1f8026ad0 @column_types={}, @columns=["count(0)"], @hash_rows=nil, @rows=[[11]]>
|
474
|
+
ARQL ❯ rs.rows
|
475
|
+
=> [[11]]
|
476
|
+
#+end_example
|
438
477
|
|
478
|
+
**** =models=
|
439
479
|
|
440
|
-
|
441
|
-
update SQL statement for the object. These two methods can also be called on an array object containing ActiveRecord
|
442
|
-
model instance objects.
|
480
|
+
=models= Returns all model classes in that namespace
|
443
481
|
|
444
482
|
#+begin_example
|
445
|
-
ARQL ❯
|
446
|
-
=>
|
483
|
+
ARQL ❯ Blog::models
|
484
|
+
=> [Blog::Person(id: integer, name: string, age: integer, created_at: datetime, updated_at: datetime), Blog::Post(id: integer, title: string, content: text, created_at: datetime, updated_at: datetime)]
|
447
485
|
#+end_example
|
448
486
|
|
487
|
+
**** =tables=
|
488
|
+
=tables= Returns all table names in the namespace
|
489
|
+
|
490
|
+
#+begin_example
|
491
|
+
ARQL ❯ Blog::tables
|
492
|
+
=> ["people", "posts"]
|
493
|
+
#+end_example
|
494
|
+
|
495
|
+
**** =model_names=
|
496
|
+
|
497
|
+
=model_names= Returns the names of all model classes in that namespace
|
498
|
+
|
499
|
+
#+begin_example
|
500
|
+
ARQL ❯ Blog::model_names
|
501
|
+
=> ["Demo::Person", "Demo::Post"]
|
502
|
+
#+end_example
|
503
|
+
|
504
|
+
**** =create_table=
|
505
|
+
|
506
|
+
=create_table= Used to create tables in the environment corresponding to the namespace
|
507
|
+
|
508
|
+
#+begin_example
|
509
|
+
ARQL ❯ Blog::create_table :people do |t|
|
510
|
+
ARQL ❯ t.string :name
|
511
|
+
ARQL ❯ t.integer :age
|
512
|
+
ARQL ❯ t.timestamps
|
513
|
+
ARQL ❯ end
|
514
|
+
#+end_example
|
515
|
+
|
516
|
+
**** =dump=
|
517
|
+
|
518
|
+
=dump= Export =mysqldump= the database corresponding to the namespace to the specified file with
|
519
|
+
|
520
|
+
#+begin_example
|
521
|
+
ARQL ❯ Blog::dump('~/data/blog.sql')
|
522
|
+
#+end_example
|
523
|
+
*** Class Methods for Models
|
524
|
+
|
525
|
+
Pry has built-in =show-source= (alias =$= ) and =show-doc= (alias =?= ) commands to view the source code and
|
526
|
+
documentation of the method. You can =show-doc= view the documentation for the method through . For example:
|
527
|
+
|
528
|
+
#+begin_example
|
529
|
+
ARQL ❯ ? Student.add_column
|
530
|
+
#+end_example
|
531
|
+
|
449
532
|
**** =to_create_sql=
|
450
533
|
|
451
|
-
You can call
|
452
|
-
corresponding to
|
534
|
+
You can call =to_create_sql= the method on any ActiveRecord model class to get the SQL statement that creates the
|
535
|
+
table corresponding to that model class.
|
453
536
|
|
454
537
|
#+begin_example
|
455
|
-
ARQL@demo247(main) [16] ❯ puts Post.to_create_sql
|
538
|
+
ARQL@demo247(main) [16] ❯ puts Blog::Post.to_create_sql
|
456
539
|
D, [2024-04-07T14:15:11.106693 #20440] DEBUG -- : SQL (24.9ms) show create table post
|
457
540
|
CREATE TABLE `post` (
|
458
541
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
@@ -470,8 +553,188 @@
|
|
470
553
|
|
471
554
|
**** =t=
|
472
555
|
|
473
|
-
|
474
|
-
|
556
|
+
|
557
|
+
=t= The class method is used to print the table structure of a model class
|
558
|
+
|
559
|
+
|
560
|
+
Executing the =Blog::Person.t= command prints the =person= definition information for the table:
|
561
|
+
|
562
|
+
#+begin_example
|
563
|
+
Table: person
|
564
|
+
+----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
|
565
|
+
| PK | Name | SQL Type | Ruby Type | Limit | Precision | Scale | Default | Nullable | Comment |
|
566
|
+
+----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
|
567
|
+
| Y | id | int(11) unsigned | integer | 4 | | | | false | |
|
568
|
+
| | name | varchar(64) | string | 64 | | | | true | |
|
569
|
+
| | age | int(11) | integer | 4 | | | | true | |
|
570
|
+
| | gender | int(4) | integer | 4 | | | | true | |
|
571
|
+
| | grade | int(4) | integer | 4 | | | | true | |
|
572
|
+
| | blood_type | varchar(4) | string | 4 | | | | true | |
|
573
|
+
+----|------------|------------------|-----------|-------|-----------|-------|---------|----------|---------+
|
574
|
+
#+end_example
|
575
|
+
|
576
|
+
|
577
|
+
=t= Accept an optional =format= named parameter with the following values:
|
578
|
+
|
579
|
+
- =md=
|
580
|
+
- =org=
|
581
|
+
- =sql=
|
582
|
+
- =terminal= (default)
|
583
|
+
|
584
|
+
例如:
|
585
|
+
|
586
|
+
#+begin_example
|
587
|
+
ARQL ❯ Blog::Person.t :sql
|
588
|
+
#+end_example
|
589
|
+
|
590
|
+
输出:
|
591
|
+
|
592
|
+
#+begin_example
|
593
|
+
CREATE TABLE `person` (
|
594
|
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
595
|
+
`name` varchar(64) DEFAULT NULL,
|
596
|
+
`age` int(11) DEFAULT NULL,
|
597
|
+
`gender` int(4) DEFAULT NULL,
|
598
|
+
`grade` int(4) DEFAULT NULL,
|
599
|
+
`blood_type` varchar(4) DEFAULT NULL,
|
600
|
+
PRIMARY KEY (`id`)
|
601
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='人员表';
|
602
|
+
#+end_example
|
603
|
+
|
604
|
+
**** =v=
|
605
|
+
|
606
|
+
|
607
|
+
=v= Class methods are used to integrate with Emacs' org babel, and can be called =v= directly in the org file to
|
608
|
+
obtain the table structure of the model class.
|
609
|
+
|
610
|
+
例如:
|
611
|
+
|
612
|
+
#+begin_example
|
613
|
+
ARQL ❯ Blog::Post.v
|
614
|
+
#+end_example
|
615
|
+
|
616
|
+
输出:
|
617
|
+
|
618
|
+
#+begin_example
|
619
|
+
ARQL@demo247(main) [10] ❯ Demo::Post.v
|
620
|
+
=> [["PK", "Name", "SQL Type", "Ruby Type", "Limit", "Precision", "Scale", "Default", "Nullable", "Comment"],
|
621
|
+
nil,
|
622
|
+
["Y", "id", "int(10) unsigned", :integer, 4, "", "", "", false, "ID"],
|
623
|
+
["", "name", "varchar(256)", :string, 256, "", "", "", true, ""],
|
624
|
+
["", "gender", "varchar(256)", :string, 256, "", "", "", true, ""],
|
625
|
+
["", "phone", "varchar(256)", :string, 256, "", "", "", true, ""],
|
626
|
+
["", "id_no", "varchar(256)", :string, 256, "", "", "", true, ""],
|
627
|
+
["", "note", "varchar(256)", :string, 256, "", "", "", true, ""],
|
628
|
+
["", "gmt_created", "datetime", :datetime, "", 0, "", "", false, "创建时间"],
|
629
|
+
["", "gmt_modified", "datetime", :datetime, "", 0, "", "", false, "最后修改时间"],
|
630
|
+
["", "sasa", "varchar(255)", :string, 255, "", "", "", true, ""]]
|
631
|
+
#+end_example
|
632
|
+
|
633
|
+
**** =vd=
|
634
|
+
|
635
|
+
|
636
|
+
Use the =visidata= display table structure
|
637
|
+
|
638
|
+
**** =table_comment=
|
639
|
+
|
640
|
+
Returns table annotations for the model
|
641
|
+
|
642
|
+
例如:
|
643
|
+
|
644
|
+
#+begin_example
|
645
|
+
ARQL ❯ Blog::Post.table_comment
|
646
|
+
#+end_example
|
647
|
+
|
648
|
+
输出:
|
649
|
+
|
650
|
+
#+begin_example
|
651
|
+
"文章表"
|
652
|
+
#+end_example
|
653
|
+
|
654
|
+
**** Add a field =add_column=
|
655
|
+
|
656
|
+
#+begin_example
|
657
|
+
Blog::Student.add_column :note, :text, comment: 'Remarks'
|
658
|
+
#+end_example
|
659
|
+
|
660
|
+
**** Modify Fields =change_column=
|
661
|
+
|
662
|
+
#+begin_example
|
663
|
+
Blog::Student.change_column :note, :string, comment: 'Remarks'
|
664
|
+
#+end_example
|
665
|
+
|
666
|
+
**** Delete the field =remove_column=
|
667
|
+
|
668
|
+
#+begin_example
|
669
|
+
Blog::Student.remove_column :note
|
670
|
+
#+end_example
|
671
|
+
|
672
|
+
**** Add an index =add_index=
|
673
|
+
|
674
|
+
#+begin_example
|
675
|
+
Blog::Student.add_index :name
|
676
|
+
Blog::Student.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
|
677
|
+
#+end_example
|
678
|
+
|
679
|
+
**** Modify field comments =change_column_comment=
|
680
|
+
|
681
|
+
#+begin_example
|
682
|
+
Blog::Student.change_column_comment :note, 'Remarks'
|
683
|
+
#+end_example
|
684
|
+
|
685
|
+
**** Modify the field defaults =change_column_default=
|
686
|
+
|
687
|
+
#+begin_example
|
688
|
+
Blog::Student.change_column_default :note, 'A note'
|
689
|
+
#+end_example
|
690
|
+
|
691
|
+
**** Modify the field name =rename_column=
|
692
|
+
|
693
|
+
#+begin_example
|
694
|
+
Blog::Student.rename_column :note, :remark
|
695
|
+
#+end_example
|
696
|
+
|
697
|
+
**** Modify the table name =rename_table=
|
698
|
+
|
699
|
+
#+begin_example
|
700
|
+
Blog::Student.rename_table :seitou
|
701
|
+
#+end_example
|
702
|
+
|
703
|
+
**** Modify table comments =change_table_comment=
|
704
|
+
|
705
|
+
#+begin_example
|
706
|
+
Blog::Student.change_table_comment from: '', to: 'students table'
|
707
|
+
#+end_example
|
708
|
+
|
709
|
+
**** Delete the table =drop_table=
|
710
|
+
|
711
|
+
#+begin_example
|
712
|
+
Blog::Student.drop_table
|
713
|
+
#+end_example
|
714
|
+
|
715
|
+
**** Delete the index =remove_index=
|
716
|
+
|
717
|
+
#+begin_example
|
718
|
+
Blog::Student.remove_index :age
|
719
|
+
Blog::Student.remove_index name: 'by_branch_party'
|
720
|
+
#+end_example
|
721
|
+
|
722
|
+
**** Query Table Comments =table_comment=
|
723
|
+
|
724
|
+
#+begin_example
|
725
|
+
Blog::Student.table_comment
|
726
|
+
#+end_example
|
727
|
+
|
728
|
+
**** Lists the indexes =indexes= of the table
|
729
|
+
|
730
|
+
#+begin_example
|
731
|
+
Blog::Student.indexes
|
732
|
+
#+end_example
|
733
|
+
*** Instance Methods for Models
|
734
|
+
**** =t=
|
735
|
+
|
736
|
+
=t= In addition to being called as a class method on an ActiveRecord model class, it can also be called as an instance
|
737
|
+
method on an ActiveRecord model instance object.
|
475
738
|
|
476
739
|
#+begin_example
|
477
740
|
ARQL ❯ Person.last.t
|
@@ -487,32 +750,46 @@
|
|
487
750
|
+----------------|-----------------|------------------|---------+
|
488
751
|
#+end_example
|
489
752
|
|
490
|
-
|
753
|
+
=t= The method can accept the following two options:
|
754
|
+
|
755
|
+
- =:compact= option to specify whether to display compactly, the value can be =true= or =false= , if compact display is
|
756
|
+
enabled, those =NULL= columns with all values will not be displayed, which is useful for viewing tables with sparse
|
757
|
+
data, such as:
|
491
758
|
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
#+END_EXAMPLE
|
497
|
-
+ =:compact= option, used to specify whether to display in compact mode. The value can be =true= or =false=. If compact
|
498
|
-
mode is enabled, columns with all NULL values will not be displayed. This is useful for viewing tables with sparse
|
759
|
+
#+begin_example
|
760
|
+
Person.last.t(compact: true)
|
761
|
+
Student.where(condition).t(compact: false)
|
762
|
+
#+end_example
|
499
763
|
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
764
|
+
- =:format= option, which is used to specify the output format, the value can be:
|
765
|
+
- =:terminal= The default output format is suitable for viewing in the terminal
|
766
|
+
- =:org= org-mode table format
|
767
|
+
- =:md= Markdown table format
|
768
|
+
|
769
|
+
**** =to_insert_sql= / =to_upsert_sql=
|
770
|
+
|
771
|
+
|
772
|
+
You can call =to_insert_sql= the / =to_upsert_sql= method on any instance of the ActiveRecord model to get the insert or
|
773
|
+
update SQL statement for that object. These two methods can also be called on an array object that contains an
|
774
|
+
ActiveRecord model instance object.
|
775
|
+
|
776
|
+
#+begin_example
|
777
|
+
ARQL ❯ Person.all.to_a.to_insert_sql
|
778
|
+
=> "INSERT INTO `person` (`id`,`name`,`age`,`gender`,`grade`,`blood_type`) VALUES (1, 'Jack', 30, NULL, NULL, NULL), (2, 'Jack', 11, 1, NULL, NULL), (3, 'Jack', 12, 1, NULL, NULL), (4, 'Jack', 30, 1, NULL, NULL), (5, 'Jack', 12, 2, NULL, NULL), (6, 'Jack', 2, 2, 2, NULL), (7, 'Jack', 3, 2, 2, NULL), (8, 'Jack', 30, 2, 2, 'AB'), (9, 'Jack', 30, 2, 2, 'AB'), (10, 'Jack', 30, 2, 2, 'AB'), (11, 'Jackson', 30, 2, 2, 'AB') ON DUPLICATE KEY UPDATE `id`=`id`;"
|
779
|
+
#+end_example
|
504
780
|
|
505
781
|
**** =v=
|
506
782
|
|
507
|
-
The =v= method is used to integrate with Emacs org babel.
|
508
783
|
|
509
|
-
|
784
|
+
=v= method is used to integrate with Emacs org babel.
|
785
|
+
|
786
|
+
***** =v= as an instance method for a model class
|
510
787
|
|
511
788
|
|
512
|
-
|
513
|
-
=['Attribute Name', 'Attribute Value', 'SQL Type', 'Comment']
|
514
|
-
|
515
|
-
return value will be rendered as a
|
789
|
+
Calling =v= the method on any ActiveRecord model instance object prints an array of the first element of the array
|
790
|
+
=['Attribute Name', 'Attribute Value', 'SQL Type', 'Comment']= , the second element =nil= , and the remaining
|
791
|
+
elements of the object's property name and value. In Emacs org-mode, if =:result= the type is =value= (the default),
|
792
|
+
this return value will be rendered as a nice table.
|
516
793
|
|
517
794
|
#+begin_example
|
518
795
|
ARQL ❯ Person.last.v
|
@@ -526,7 +803,7 @@
|
|
526
803
|
["blood_type", "AB", "varchar(4)", ""]]
|
527
804
|
#+end_example
|
528
805
|
|
529
|
-
*****
|
806
|
+
***** An array that contains only model instances
|
530
807
|
|
531
808
|
#+begin_example
|
532
809
|
ARQL ❯ Person.all.to_a.v
|
@@ -545,7 +822,7 @@
|
|
545
822
|
[11, "Jackson", 30, 2, 2, "AB"]]
|
546
823
|
#+end_example
|
547
824
|
|
548
|
-
*****
|
825
|
+
***** An array containing only homogeneous hash objects
|
549
826
|
|
550
827
|
#+begin_example
|
551
828
|
ARQL ❯ arr = [{name: 'Jack', age: 10}, {name: 'Lucy', age: 20}]
|
@@ -554,561 +831,473 @@
|
|
554
831
|
=> [[:name, :age], nil, ["Jack", 10], ["Lucy", 20]]
|
555
832
|
#+end_example
|
556
833
|
|
557
|
-
**** =
|
558
|
-
|
559
|
-
#+begin_example
|
560
|
-
ARQL ❯ rs = q 'select count(0) from person;'
|
561
|
-
=> #<ActiveRecord::Result:0x00007fd1f8026ad0 @column_types={}, @columns=["count(0)"], @hash_rows=nil, @rows=[[11]]>
|
562
|
-
ARQL ❯ rs.rows
|
563
|
-
=> [[11]]
|
564
|
-
#+end_example
|
565
|
-
|
566
|
-
**** JSON conversion and formatting
|
567
|
-
|
568
|
-
Call the =j= method on any object to get a JSON-formatted string, and call the =jj= method to get a formatted JSON string.
|
569
|
-
|
570
|
-
Use the =jp= method to print JSON and the =jjp= method to print formatted JSON.
|
834
|
+
**** =dump=
|
571
835
|
|
572
|
-
**** The =$C= Global Variables
|
573
836
|
|
837
|
+
To export the instance object as =INSERT= a SQL statement, see the "dump data" section below
|
574
838
|
|
575
|
-
|
839
|
+
**** =write_excel= / =write_csv=
|
576
840
|
|
577
|
-
The =q= method mentioned above is actually the =$C.exec_query= method. Other methods of the =$C= object are also useful:
|
578
841
|
|
579
|
-
|
580
|
-
|
581
|
-
ARQL ❯ $C.create_table :post, id: false, primary_key: :id do |t|
|
582
|
-
ARQL ❯ t.column :id, :bigint, precison: 19, comment: 'ID'
|
583
|
-
ARQL ❯ t.column :name, :string, comment: '名称'
|
584
|
-
ARQL ❯ t.column :gmt_created, :datetime, comment: '创建时间'
|
585
|
-
ARQL ❯ t.column :gmt_modified, :datetime, comment: '最后修改时间'
|
586
|
-
ARQL ❯ end
|
587
|
-
#+end_example
|
842
|
+
To export the instance object as an Excel or CSV file, see the "Reading and Writing Excel and CSV Files" section below
|
843
|
+
*** =ActiveRecord::Relation= / =ActiveRecord::Result= / =Ransack::Search= / =Array=
|
588
844
|
|
589
|
-
|
590
|
-
|
591
|
-
#+begin_example
|
592
|
-
ARQL ❯ create_table :post, id: false, primary_key: :id do |t|
|
593
|
-
ARQL ❯ t.column :id, :bigint, precison: 19, comment: 'ID'
|
594
|
-
ARQL ❯ t.column :name, :string, comment: '名称'
|
595
|
-
ARQL ❯ t.column :gmt_created, :datetime, comment: '创建时间'
|
596
|
-
ARQL ❯ t.column :gmt_modified, :datetime, comment: '最后修改时间'
|
597
|
-
ARQL ❯ end
|
598
|
-
#+end_example
|
845
|
+
=ActiveRecord::Relation= / =ActiveRecord::Result= / =Ransack::Search= Logically they can all be thought of as arrays, so
|
846
|
+
these methods can be called on these objects:
|
599
847
|
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
$C.add_column :post, :note, :string, comment: 'the note'
|
604
|
-
#+end_example
|
605
|
-
|
606
|
-
The =add_column= method is also added to the class methods of the model class, so you can also call the
|
607
|
-
=add_column= method directly on the model class:
|
608
|
-
|
609
|
-
#+begin_example
|
610
|
-
Post.add_column :note, :string, comment: 'the note'
|
611
|
-
#+end_example
|
612
|
-
|
613
|
-
***** Change Column
|
848
|
+
**** =t=
|
849
|
+
=t= Methods can also be called on an array that contains an ActiveRecord instance, or on a =ActiveRecord::Relation= /
|
850
|
+
=ActiveRecord::Result= / =Ransack::Search= object.
|
614
851
|
|
615
|
-
|
616
|
-
|
617
|
-
|
852
|
+
#+begin_example
|
853
|
+
ARQL ❯ Person.last(2).t
|
854
|
+
+----+----------+--------+----------------------------------+-------+------+---------------------------+---------------------------+
|
855
|
+
| id | name | gender | id_no | phone | note | gmt_created | gmt_modified |
|
856
|
+
+----+----------+--------+----------------------------------+-------+------+---------------------------+---------------------------+
|
857
|
+
| 90 | Zhangsan | M | f09288fb381cc47dd2e56389cf15f0bf | | | 2021-04-26 15:32:05 +0800 | 2021-04-26 15:32:05 +0800 |
|
858
|
+
| 91 | Lisi | F | fb6fea4b23b1d3c54739774946246e4c | | | 2021-04-26 15:32:05 +0800 | 2021-04-26 15:32:05 +0800 |
|
859
|
+
+----+----------+--------+----------------------------------+-------+------+---------------------------+---------------------------+
|
860
|
+
#+end_example
|
618
861
|
|
619
|
-
The =change_column= method is also added to the class methods of the model class, so you can also call the
|
620
|
-
=change_column= method directly on the model class:
|
621
862
|
|
622
|
-
|
623
|
-
|
624
|
-
#+end_example
|
863
|
+
When used as an array and "array-like" object instance method, =t= the method can accept multiple parameters for
|
864
|
+
filtering attributes, which can be:
|
625
865
|
|
626
|
-
|
866
|
+
- string or Symbol, which literally matches the property
|
867
|
+
- Regular expressions to make regular matches to attributes
|
627
868
|
|
628
|
-
#+begin_example
|
629
|
-
$C.remove_column :post, :note
|
630
|
-
#+end_example
|
631
869
|
|
632
|
-
|
633
|
-
=remove_column= method directly on the model class:
|
870
|
+
For example, only =name= show , =gender= and all properties whose names contain the =time= word :
|
634
871
|
|
635
|
-
|
636
|
-
|
637
|
-
|
872
|
+
#+begin_example
|
873
|
+
ARQL ❯ Person.last(2).t('name', :gender, /time/i)
|
874
|
+
#+end_example
|
638
875
|
|
639
|
-
***** Drop Table
|
640
876
|
|
641
|
-
|
642
|
-
$C.drop_table :post
|
643
|
-
#+end_example
|
877
|
+
As an example of an array and an Array-like object, =t= the following three options can also be accepted:
|
644
878
|
|
645
|
-
|
646
|
-
|
879
|
+
- =:except= option, which allows you to specify a property name that is not displayed, and the value can be a string
|
880
|
+
or a regular expression, for example:
|
647
881
|
|
648
|
-
|
649
|
-
|
650
|
-
|
882
|
+
#+begin_example
|
883
|
+
Person.last(10).t(except: 'id')
|
884
|
+
Student.where(condition).t(except: /id|name/)
|
885
|
+
#+end_example
|
651
886
|
|
652
|
-
|
887
|
+
- =:compact= option to specify whether to display compactly, the value can be =true= or =false= , if compact display
|
888
|
+
is enabled, those =NULL= columns with all values will not be displayed, which is useful for viewing tables with
|
889
|
+
sparse data, such as:
|
653
890
|
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
891
|
+
#+begin_example
|
892
|
+
Person.last(10).t(compact: true)
|
893
|
+
Student.where(condition).t(compact: false)
|
894
|
+
#+end_example
|
658
895
|
|
659
|
-
|
660
|
-
|
896
|
+
- =:format= option, which is used to specify the output format, the value can be:
|
897
|
+
- =:terminal= The default output format is suitable for viewing in the terminal
|
898
|
+
- =:org= org-mode table format
|
899
|
+
- =:md= Markdown table format
|
661
900
|
|
662
|
-
|
663
|
-
Post.add_index :name
|
664
|
-
Post.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
|
665
|
-
#+end_example
|
901
|
+
**** =v=
|
666
902
|
|
667
|
-
**** Kernel Extensions
|
668
903
|
|
669
|
-
|
670
|
-
The following are the =Kernel= methods extended by Arql:
|
904
|
+
=v= method is used to integrate with Emacs org babel.
|
671
905
|
|
672
|
-
|
906
|
+
#+begin_example
|
907
|
+
ARQL ❯ Person.last.v
|
908
|
+
=> [["Attribute Name", "Attribute Value", "SQL Type", "Comment"],
|
909
|
+
nil,
|
910
|
+
["id", 11, "int(11) unsigned", ""],
|
911
|
+
["name", "Jackson", "varchar(64)", ""],
|
912
|
+
["age", 30, "int(11)", ""],
|
913
|
+
["gender", 2, "int(4)", ""],
|
914
|
+
["grade", 2, "int(4)", ""],
|
915
|
+
["blood_type", "AB", "varchar(4)", ""]]
|
916
|
+
#+end_example
|
673
917
|
|
918
|
+
**** =vd=
|
674
919
|
|
675
|
-
#+BEGIN_EXAMPLE
|
676
|
-
ARQL ❯ ? create_table
|
677
|
-
#+END_EXAMPLE
|
678
920
|
|
921
|
+
Use to =visidata= display "array" data
|
679
922
|
|
680
|
-
|
681
|
-
#+BEGIN_EXAMPLE
|
682
|
-
create_table :post, id: false, primary_key: :id do |t|
|
683
|
-
t.column :id, :bigint, precison: 19, comment: 'ID'
|
684
|
-
t.column :name, :string, comment: '名称'
|
685
|
-
t.column :gmt_created, :datetime, comment: '创建时间'
|
686
|
-
t.column :gmt_modified, :datetime, comment: '最后修改时间'
|
687
|
-
end
|
688
|
-
#+END_EXAMPLE
|
689
|
-
***** =create_join_table=
|
690
|
-
#+BEGIN_EXAMPLE
|
691
|
-
create_join_table :products, :categories do |t|
|
692
|
-
t.index :product_id
|
693
|
-
t.index :category_id
|
694
|
-
end
|
695
|
-
#+END_EXAMPLE
|
696
|
-
***** =drop_table=
|
697
|
-
#+BEGIN_EXAMPLE
|
698
|
-
drop_table :post
|
699
|
-
#+END_EXAMPLE
|
700
|
-
***** =drop_join_table=
|
701
|
-
#+BEGIN_EXAMPLE
|
702
|
-
drop_join_table :products, :categories
|
703
|
-
#+END_EXAMPLE
|
704
|
-
***** =rename_table=
|
705
|
-
#+BEGIN_EXAMPLE
|
706
|
-
rename_table :post, :posts
|
707
|
-
#+END_EXAMPLE
|
923
|
+
**** =write_csv= / =write_excel=
|
708
924
|
|
709
|
-
***** =print_tables=
|
710
925
|
|
711
|
-
|
926
|
+
=write_csv= and =write_excel= Used to export Array data to CSV or Excel files, see the "Reading and Writing Excel and
|
927
|
+
CSV Files" section below
|
712
928
|
|
713
|
-
|
714
|
-
+ org-mode table format: ~print_tables(:org)~
|
715
|
-
+ create table SQL: ~print_tables(:sql)~
|
929
|
+
**** =dump=
|
716
930
|
|
717
|
-
**** Model Class Methods Extensions
|
718
931
|
|
719
|
-
|
720
|
-
|
721
|
-
|
932
|
+
=dump= The method is used to export the ActiveRecord::Relation / ActiveRecord::Result / Ransack::Search object as an
|
933
|
+
INSERT SQL statement, see the "dump data" section below
|
934
|
+
*** Extension =Kernel= Methods
|
935
|
+
|
936
|
+
The following methods corresponding to a DDL operation have a limitation when used: if multiple environments are
|
937
|
+
connected, the environment name must be specified via =:env= the option when calling these methods. For example:
|
722
938
|
|
723
|
-
|
724
|
-
|
939
|
+
#+begin_src ruby
|
940
|
+
create_table :users, env: 'development', comment: 'the user table' do |t|
|
941
|
+
t.string :name, comment: 'User Name'
|
942
|
+
t.integer :age, comment: 'User Age'
|
943
|
+
end
|
944
|
+
#+end_src
|
725
945
|
|
726
|
-
|
727
|
-
ARQL ❯ ? Student.add_column
|
728
|
-
#+END_EXAMPLE
|
946
|
+
**** Create a table =create_table=
|
729
947
|
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
948
|
+
#+begin_example
|
949
|
+
create_table :post, id: false, primary_key: :id do |t|
|
950
|
+
t.column :id, :bigint, precison: 19, comment: 'ID'
|
951
|
+
t.column :name, :string, comment: 'Post Name'
|
952
|
+
t.column :gmt_created, :datetime, comment: 'Created Time'
|
953
|
+
t.column :gmt_modified, :datetime, comment: 'Modified Time'
|
954
|
+
end
|
955
|
+
#+end_example
|
734
956
|
|
735
|
-
|
736
|
-
#+BEGIN_EXAMPLE
|
737
|
-
Student.change_column :note, :string, comment: '备注'
|
738
|
-
#+END_EXAMPLE
|
957
|
+
**** Create an intermediate table =create_join_table= for many-to-many relationships
|
739
958
|
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
959
|
+
#+begin_example
|
960
|
+
create_join_table :products, :categories do |t|
|
961
|
+
t.index :product_id
|
962
|
+
t.index :category_id
|
963
|
+
end
|
964
|
+
#+end_example
|
744
965
|
|
745
|
-
|
746
|
-
#+BEGIN_EXAMPLE
|
747
|
-
Student.add_index :name
|
748
|
-
Student.add_index [:branch_id, :party_id], unique: true, name: 'by_branch_party'
|
749
|
-
#+END_EXAMPLE
|
966
|
+
**** Delete the table =drop_table=
|
750
967
|
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
#+END_EXAMPLE
|
968
|
+
#+begin_example
|
969
|
+
drop_table :post
|
970
|
+
#+end_example
|
755
971
|
|
756
|
-
|
757
|
-
#+BEGIN_EXAMPLE
|
758
|
-
Student.change_column_default :note, '默认值'
|
759
|
-
#+END_EXAMPLE
|
972
|
+
**** Delete intermediate tables =drop_join_table= for many-to-many relationships
|
760
973
|
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
#+END_EXAMPLE
|
974
|
+
#+begin_example
|
975
|
+
drop_join_table :products, :categories
|
976
|
+
#+end_example
|
765
977
|
|
766
|
-
|
767
|
-
#+BEGIN_EXAMPLE
|
768
|
-
Student.rename_table :seitou
|
769
|
-
#+END_EXAMPLE
|
978
|
+
**** Modify the table name =rename_table=
|
770
979
|
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
#+END_EXAMPLE
|
980
|
+
#+begin_example
|
981
|
+
rename_table :post, :posts
|
982
|
+
#+end_example
|
775
983
|
|
776
|
-
|
777
|
-
#+BEGIN_EXAMPLE
|
778
|
-
Student.drop_table
|
779
|
-
#+END_EXAMPLE
|
984
|
+
**** =models=
|
780
985
|
|
781
|
-
|
782
|
-
#+BEGIN_EXAMPLE
|
783
|
-
Student.remove_index :age
|
784
|
-
Student.remove_index name: 'by_branch_party'
|
785
|
-
#+END_EXAMPLE
|
986
|
+
Returns the model classes that will be under all environment namespaces
|
786
987
|
|
787
|
-
|
788
|
-
#+BEGIN_EXAMPLE
|
789
|
-
Student.table_comment
|
790
|
-
#+END_EXAMPLE
|
988
|
+
**** =table_names=
|
791
989
|
|
792
|
-
|
793
|
-
#+BEGIN_EXAMPLE
|
794
|
-
Student.indexes
|
795
|
-
#+END_EXAMPLE
|
990
|
+
Returns table names for all environments
|
796
991
|
|
797
|
-
****
|
992
|
+
**** =model_names=
|
798
993
|
|
799
|
-
|
800
|
-
Arql also provides methods for reading and writing CSV files.
|
994
|
+
Returns the model class names for all environments
|
801
995
|
|
802
|
-
|
996
|
+
**** =q=
|
803
997
|
|
804
|
-
Arql adds a =parse_excel= method to the =Kernel= module, which can be used to parse Excel files. For example:
|
805
998
|
|
806
|
-
|
807
|
-
|
808
|
-
|
999
|
+
If you specify only one environment, you can use =q= methods to execute native SQL queries without specifying a
|
1000
|
+
namespace module =q= in =Blog::q= front of
|
1001
|
+
*** Other Extension Methods
|
809
1002
|
|
810
|
-
|
1003
|
+
**** JSON conversion and formatting
|
811
1004
|
|
812
|
-
|
1005
|
+
Calling =j= the method on any object will result in a JSON-formatted string, and the calling =jj= method will result in
|
1006
|
+
a formatted JSON string.
|
813
1007
|
|
814
|
-
|
815
|
-
ARQL ❯ 'path/to/excel.xlsx'.parse_excel
|
816
|
-
#+END_EXAMPLE
|
1008
|
+
Use =jp= the method to print the JSON, and use the method to =jjp= print the formatted JSON.
|
817
1009
|
|
818
|
-
|
819
|
-
sheet, which is a two-dimensional array. For example:
|
1010
|
+
**** =String=
|
820
1011
|
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
['A3', 'B3', 'C3']
|
832
|
-
]
|
833
|
-
}
|
834
|
-
#+END_EXAMPLE
|
1012
|
+
1. =Srting#p=
|
1013
|
+
=p= The method is defined as follows:
|
1014
|
+
#+begin_example
|
1015
|
+
class String
|
1016
|
+
def p
|
1017
|
+
puts self
|
1018
|
+
end
|
1019
|
+
end
|
1020
|
+
#+end_example
|
1021
|
+
="hello".p= Equivalent to =puts "hello"= .
|
835
1022
|
|
836
|
-
|
1023
|
+
2. =String#parse=
|
1024
|
+
For a string representing a file path, you can call =parse= the method to parse Excel, CSV, and
|
1025
|
+
JSON files by the suffix in the file path.
|
1026
|
+
#+begin_example
|
1027
|
+
excel = 'path/to/excel.xlsx'.parse
|
1028
|
+
csv = 'path/to/csv.csv'.parse
|
1029
|
+
json = 'path/to/json.json'.parse
|
1030
|
+
#+end_example
|
837
1031
|
|
838
|
-
|
839
|
-
be used to generate Excel files:
|
1032
|
+
**** =ID=
|
840
1033
|
|
841
1034
|
|
842
|
-
|
1035
|
+
Arql provides a =ID= class that generates snowflake algorithm IDs and UUIDs.
|
843
1036
|
|
844
|
-
|
845
|
-
|
846
|
-
|
1037
|
+
#+begin_example
|
1038
|
+
id = ID.long # Generate a snowflake algorithm ID
|
1039
|
+
id = ID.uuid # Generate a UUID
|
1040
|
+
#+end_example
|
1041
|
+
*** Read and write Excel and CSV files
|
847
1042
|
|
848
|
-
|
849
|
-
|
1043
|
+
Arql integrates =caxlsx= with =roo= the and two Excel libraries, providing a way to parse and generate Excel files. Arql
|
1044
|
+
also provides methods for reading and writing CSV files.
|
850
1045
|
|
851
|
-
|
852
|
-
+ An array, representing a row of data
|
853
|
-
+ A Hash object, representing a row of data, where the key is the column name and the value is the column value
|
854
|
-
+ An =ActiveRecord::Base= object, representing a row of data
|
855
|
-
+ A Hash object, which contains two key-value pairs:
|
856
|
-
+ =:fields=, an array representing the column names
|
857
|
-
+ =:data=, a two-dimensional array representing the data
|
1046
|
+
**** Parse Excel
|
858
1047
|
|
859
|
-
|
1048
|
+
Arql adds =parse_excel= methods to the =Kernel= module that can be used to parse Excel files. For example:
|
860
1049
|
|
861
|
-
|
862
|
-
|
863
|
-
|
1050
|
+
#+BEGIN_EXAMPLE
|
1051
|
+
ARQL ❯ parse_excel 'path/to/excel.xlsx'
|
1052
|
+
#+END_EXAMPLE
|
864
1053
|
|
865
|
-
|
1054
|
+
You can use in the file path to =~/= represent the user's home directory, and Arql will be automatically expanded.
|
866
1055
|
|
867
|
-
|
868
|
-
based on the first element of the array:
|
869
|
-
- If the element is an ActiveRecord::Base object, all attribute names of the object (i.e., the database field
|
870
|
-
list) will be used as column names
|
871
|
-
- If the element is a Hash object, all keys of the Hash will be used as column names
|
872
|
-
+ =sheet_name= Specifies the sheet name. If not specified, the default sheet name =Sheet1= will be used
|
1056
|
+
You can also call =parse_excel= the Method on an object that represents the path to the =String= file:
|
873
1057
|
|
874
|
-
|
875
|
-
|
1058
|
+
#+BEGIN_EXAMPLE
|
1059
|
+
ARQL ❯ 'path/to/excel.xlsx'.parse_excel
|
1060
|
+
#+END_EXAMPLE
|
876
1061
|
|
877
|
-
|
878
|
-
|
879
|
-
+ An array, representing a row of data
|
1062
|
+
=parse_excel= The method returns an =Hash= object, Key is the name of the Sheet, Value is the data for the Sheet, and
|
1063
|
+
Value is a two-dimensional array. For example:
|
880
1064
|
|
881
|
-
|
1065
|
+
#+BEGIN_EXAMPLE
|
1066
|
+
{
|
1067
|
+
'Sheet1' => [
|
1068
|
+
['A1', 'B1', 'C1'],
|
1069
|
+
['A2', 'B2', 'C2'],
|
1070
|
+
['A3', 'B3', 'C3']
|
1071
|
+
],
|
1072
|
+
'Sheet2' => [
|
1073
|
+
['A1', 'B1', 'C1'],
|
1074
|
+
['A2', 'B2', 'C2'],
|
1075
|
+
['A3', 'B3', 'C3']
|
1076
|
+
]
|
1077
|
+
}
|
1078
|
+
#+END_EXAMPLE
|
882
1079
|
|
883
|
-
|
884
|
-
ARQL ❯ Student.find(123).write_excel 'path/to/excel.xlsx', sheet_name: '学生数据'
|
885
|
-
#+END_EXAMPLE
|
1080
|
+
**** Generate Excel
|
886
1081
|
|
887
|
-
|
888
|
-
|
1082
|
+
Arql adds a =write_excel= method for =Hash= the / =Array= / =ActiveRecord::Relation= =ActiveRecord::Base= / object,
|
1083
|
+
which can be used to generate an Excel file:
|
889
1084
|
|
890
|
-
|
1085
|
+
***** Generate Excel from Hash objects
|
891
1086
|
|
892
|
-
|
893
|
-
|
894
|
-
|
1087
|
+
#+BEGIN_EXAMPLE
|
1088
|
+
ARQL ❯ obj.write_excel 'path/to/excel.xlsx'
|
1089
|
+
#+END_EXAMPLE
|
895
1090
|
|
896
|
-
|
897
|
-
|
1091
|
+
=Hash#write_excel= The key of the hash object is the name of the sheet, the value is the data of the sheet, and the type
|
1092
|
+
of value can be:
|
898
1093
|
|
899
|
-
|
1094
|
+
- An array, the elements of which can be:
|
1095
|
+
- An array representing a row of data
|
1096
|
+
- A hash object that represents a row of data, with Key being the column name and Value being the column value
|
1097
|
+
- An ActiveRecord::Base object that represents a row of data
|
1098
|
+
- A hash object that contains two key-value pairs:
|
1099
|
+
- =:fields= , an array representing the column name
|
1100
|
+
- =:data= , a two-dimensional array that represents data
|
900
1101
|
|
901
|
-
|
1102
|
+
***** Generate Excel from Array objects
|
902
1103
|
|
903
1104
|
#+BEGIN_EXAMPLE
|
904
|
-
ARQL ❯
|
1105
|
+
ARQL ❯ obj.write_excel 'path/to/excel.xlsx', :name, :age, :gender, sheet_name: 'Order Data'
|
905
1106
|
#+END_EXAMPLE
|
906
1107
|
|
1108
|
+
Thereinto:
|
907
1109
|
|
908
|
-
|
909
|
-
|
910
|
-
|
1110
|
+
- =:name, :age, :gender= These parameters are column names, and if not specified, the column names will be determined
|
1111
|
+
based on the first element of the array:
|
1112
|
+
- If the element is =ActiveRecord::Base= an object, all of the object's property names (i.e., a list of database
|
1113
|
+
fields) are used as the column names
|
1114
|
+
- If the element is =Hash= an object, the All Keys are used =Hash= as the column name
|
1115
|
+
- =sheet_name= Specify a sheet name, or if you don't =Sheet1= , the default sheet name is used
|
911
1116
|
|
912
|
-
- =encoding=, specifies the encoding of the CSV file, which is =UTF-16= (with BOM) by default
|
913
|
-
- =headers=, specifies whether to include the header, which is =false= by default
|
914
|
-
- =col_sep=, specifies the column separator, which is =\t= by default
|
915
|
-
- =row_sep=, specifies the row separator, which is =\r\n= by default
|
916
1117
|
|
1118
|
+
=Array= Each element of the object represents a row of data, requiring =Array#write_excel= each element of the Array
|
1119
|
+
object to:
|
917
1120
|
|
918
|
-
|
1121
|
+
- An =ActiveRecord::Base= object
|
1122
|
+
- An =Hash= object that represents a row of data, with Key being the column name and Value being the column value
|
1123
|
+
- An array representing a row of data
|
919
1124
|
|
920
|
-
|
921
|
-
You can also call the =parse_csv= method on a String object representing the file path:
|
1125
|
+
***** Generate Excel from =ActiveRecord::Base= objects
|
922
1126
|
|
923
1127
|
#+BEGIN_EXAMPLE
|
924
|
-
ARQL ❯ 'path/to/
|
1128
|
+
ARQL ❯ Student.find(123).write_excel 'path/to/excel.xlsx', sheet_name: 'Student Data'
|
925
1129
|
#+END_EXAMPLE
|
926
1130
|
|
927
|
-
|
928
|
-
|
929
|
-
Arql adds the =write_csv= method to =Array= / =ActiveRecord::Relation= / =ActiveRecord::Base= objects, which can be used to
|
930
|
-
generate CSV files:
|
931
|
-
|
932
|
-
****** Generate CSV from =Array= Object
|
933
|
-
|
934
|
-
#+BEGIN_EXAMPLE
|
935
|
-
ARQL ❯ obj.write_csv 'path/to/csv.csv', :name, :age, :gender, sheet_name: '订单数据'
|
936
|
-
#+END_EXAMPLE
|
937
|
-
|
938
|
-
The usage is similar to the write_excel method of =Array= objects.
|
939
|
-
|
1131
|
+
=ActiveRecord::Base= The =write_excel= object is actually the method that wraps the =ActiveRecord::Base= object into an
|
1132
|
+
object with =Array= only one element, and then calls =Array= the =write_excel= method.
|
940
1133
|
|
941
|
-
|
1134
|
+
***** Generate Excel from =ActiveRecord::Relation= objects
|
942
1135
|
|
943
|
-
|
944
|
-
|
945
|
-
|
1136
|
+
#+BEGIN_EXAMPLE
|
1137
|
+
ARQL ❯ Student.where(gender: 'M').write_excel 'path/to/excel.xlsx', sheet_name: 'Male Students'
|
1138
|
+
#+END_EXAMPLE
|
1139
|
+
=ActiveRecord::Relation= The =write_excel= object is actually the =write_excel= method =Array= that converts the
|
1140
|
+
=ActiveRecord::Relation= object into an =Array= object and then calls it.
|
946
1141
|
|
947
|
-
|
1142
|
+
**** Parse CSV
|
948
1143
|
|
949
|
-
|
1144
|
+
Arql provides =parse_csv= methods that can be used to parse CSV files:
|
950
1145
|
|
1146
|
+
#+begin_example
|
1147
|
+
ARQL ❯ parse_csv 'path/to/csv.csv'
|
1148
|
+
#+end_example
|
951
1149
|
|
952
|
-
|
953
|
-
ARQL ❯ Student.where(gender: 'M').write_csv 'path/to/csv.csv', sheet_name: '男学生'
|
954
|
-
#+END_EXAMPLE
|
1150
|
+
=parse_csv= The method returns a CSV object from a standard library.
|
955
1151
|
|
1152
|
+
=parse_csv= There can be the following optional parameters:
|
956
1153
|
|
957
|
-
|
1154
|
+
- =encoding= , specifies the encoding of the CSV file, default is =UTF-16= (with BOM)
|
1155
|
+
- =headers= , specifies whether to include a table header, which is the default value =false=
|
1156
|
+
- =col_sep= to specify the column separator, which defaults to =\t=
|
1157
|
+
- =row_sep= , specifies the row separator, which is =\r\n= the default
|
958
1158
|
|
959
|
-
|
1159
|
+
(The above default values are actually the default configuration used by Microsoft Office Excel when saving CSV files)
|
960
1160
|
|
961
|
-
|
1161
|
+
You can also call =parse_csv= the Method on an object that represents the path to the =String= file:
|
962
1162
|
|
963
|
-
|
964
|
-
|
1163
|
+
#+BEGIN_EXAMPLE
|
1164
|
+
ARQL ❯ 'path/to/csv.csv'.parse_csv
|
1165
|
+
#+END_EXAMPLE
|
965
1166
|
|
1167
|
+
**** Generate a CSV
|
966
1168
|
|
967
|
-
|
1169
|
+
Arql adds a method for =Array= the / =ActiveRecord::Relation= / =ActiveRecord::Base= object, which can be used to
|
1170
|
+
generate a CSV =write_csv= file:
|
1171
|
+
***** Generate a CSV from an Array object
|
968
1172
|
|
969
1173
|
#+BEGIN_EXAMPLE
|
970
|
-
ARQL ❯ obj.
|
1174
|
+
ARQL ❯ obj.write_csv 'path/to/csv.csv', :name, :age, :gender, sheet_name: 'Order Data'
|
971
1175
|
#+END_EXAMPLE
|
972
1176
|
|
1177
|
+
The usage is similar to the =Array= object's =write_excel= method.
|
973
1178
|
|
974
|
-
|
975
|
-
|
976
|
-
The =batch_size= parameter specifies the data queried in each batch, with a default value of 500
|
977
|
-
|
978
|
-
***** Dump data from =ActiveRecord::Base= Object
|
1179
|
+
***** Generate a CSV from an =ActiveRecord::Base= object
|
979
1180
|
|
980
1181
|
#+BEGIN_EXAMPLE
|
981
|
-
ARQL ❯ Student.find(123).
|
1182
|
+
ARQL ❯ Student.find(123).write_csv 'path/to/csv.csv', sheet_name: 'Student Data'
|
982
1183
|
#+END_EXAMPLE
|
983
1184
|
|
1185
|
+
The usage is similar to the =ActiveRecord::Base= object's =write_excel= method.
|
984
1186
|
|
985
|
-
|
986
|
-
with only one element, and then calls the =dump= method of =Array=.
|
987
|
-
|
988
|
-
***** Dump data from =ActiveRecord::Relation= Object
|
1187
|
+
***** Generate a CSV from an =ActiveRecord::Relation= object
|
989
1188
|
|
990
1189
|
#+BEGIN_EXAMPLE
|
991
|
-
ARQL ❯ Student.where(gender: 'M').
|
1190
|
+
ARQL ❯ Student.where(gender: 'M').write_csv 'path/to/csv.csv', sheet_name: 'Make Students'
|
992
1191
|
#+END_EXAMPLE
|
993
1192
|
|
1193
|
+
The usage is similar to the =ActiveRecord::Relation= object's =write_excel= method.
|
994
1194
|
|
995
|
-
|
996
|
-
and then calls the =dump= method of Array.
|
1195
|
+
*** dump data
|
997
1196
|
|
998
1197
|
|
999
|
-
|
1198
|
+
Note: Only MySQL databases are supported
|
1000
1199
|
|
1001
|
-
#+BEGIN_EXAMPLE
|
1002
|
-
ARQL ❯ Student.dump 'path/to/dump.sql', no_create_table: false
|
1003
|
-
#+END_EXAMPLE
|
1004
1200
|
|
1005
|
-
|
1201
|
+
Arql adds =dump= methods for objects such as =Array= / =ActiveRecord::Base= / =ActiveRecord::Relation= that can be used
|
1202
|
+
to export data to a SQL file:
|
1006
1203
|
|
1007
|
-
|
1204
|
+
**** Export data from an Array object
|
1008
1205
|
|
1206
|
+
#+begin_example
|
1207
|
+
ARQL ❯ obj.dump 'path/to/dump.sql', batch_size: 5000
|
1208
|
+
#+end_example
|
1009
1209
|
|
1010
1210
|
|
1011
|
-
|
1211
|
+
=Array= Each element of an object must be an =ActiveRecord::Base= object
|
1012
1212
|
|
1013
|
-
#+BEGIN_EXAMPLE
|
1014
|
-
ARQL ❯ $C.dump 'path/to/dump.sql', no_create_db: false
|
1015
|
-
#+END_EXAMPLE
|
1016
1213
|
|
1214
|
+
=batch_size= The parameter specifies the data queried out for each batch, and the default value is 500
|
1017
1215
|
|
1018
|
-
|
1216
|
+
**** Export data from the ActiveRecord::Base object
|
1019
1217
|
|
1020
|
-
|
1218
|
+
#+begin_example
|
1219
|
+
ARQL ❯ Student.find(123).dump 'path/to/dump.sql', batch_size: 5000
|
1220
|
+
#+end_example
|
1021
1221
|
|
1022
1222
|
|
1023
|
-
|
1223
|
+
=ActiveRecord::Base= An object's =dump= method is actually a =dump= method that wraps the =ActiveRecord::Base= object
|
1224
|
+
into an =Array= object with only one element, and then calls =Array= the method.
|
1024
1225
|
|
1025
|
-
|
1226
|
+
**** Export data from the ActiveRecord::Relation object
|
1026
1227
|
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
+ =lineplot=
|
1031
|
-
+ =lineplots=
|
1032
|
-
+ =scatter=
|
1033
|
-
+ =density=
|
1034
|
-
+ =boxplot=
|
1228
|
+
#+begin_example
|
1229
|
+
ARQL ❯ Student.where(gender: 'M').dump 'path/to/dump.sql', batch_size: 5000
|
1230
|
+
#+end_example
|
1035
1231
|
|
1036
|
-
Example:
|
1037
1232
|
|
1038
|
-
|
1233
|
+
=ActiveRecord::Relation= The =dump= object is actually the =dump= method =Array= that converts the
|
1234
|
+
=ActiveRecord::Relation= object into an =Array= object and then calls it.
|
1039
1235
|
|
1040
|
-
|
1041
|
-
ARQL@demo247(main) [44] ❯ Student.pluck(:gender)
|
1042
|
-
=> ["M", "M", "M", "M", "M", "M", "M", "F", "M", "F", "M", "M", "M", "M", "M"]
|
1043
|
-
ARQL@demo247(main) [45] ❯ Student.pluck(:gender).countplot
|
1044
|
-
┌ ┐
|
1045
|
-
M ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 13.0
|
1046
|
-
F ┤■■■■■ 2.0
|
1047
|
-
└ ┘
|
1048
|
-
#+END_EXAMPLE
|
1236
|
+
**** Call the dump class method of ActiveRecord::Base
|
1049
1237
|
|
1050
|
-
|
1238
|
+
#+begin_example
|
1239
|
+
ARQL ❯ Student.dump 'path/to/dump.sql', no_create_table: false
|
1240
|
+
#+end_example
|
1051
1241
|
|
1052
|
-
#+BEGIN_EXAMPLE
|
1053
|
-
ARQL@jicai.dev(main) [18] ❯ Order.last(20).pluck(:order_sum)
|
1054
|
-
=> [0.21876e5, 0.336571e5, 0.1934e5, 0.966239e4, 0.38748e3, 0.31092e4, 0.483e5, 0.445121e5, 0.1305e4, 0.2296e6, 0.943e5, 0.352e4, 0.3756e5, 0.323781e5, 0.7937622e5, 0.982e4, 0.338393e5, 0.316597e5, 0.213678e5, 0.336845e5]
|
1055
|
-
ARQL@jicai.dev(main) [19] ❯ Order.last(20).pluck(:order_sum).histo
|
1056
|
-
┌ ┐
|
1057
|
-
[ 0.0, 50000.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 17
|
1058
|
-
[ 50000.0, 100000.0) ┤▇▇▇▇ 2
|
1059
|
-
[100000.0, 150000.0) ┤ 0
|
1060
|
-
[150000.0, 200000.0) ┤ 0
|
1061
|
-
[200000.0, 250000.0) ┤▇▇ 1
|
1062
|
-
└ ┘
|
1063
|
-
Frequency
|
1064
1242
|
|
1065
|
-
|
1243
|
+
This method will export all the data in the =Student= table to a SQL file via =mysqldump= the command.
|
1066
1244
|
|
1067
|
-
**** =String=
|
1068
|
-
|
1069
|
-
***** =Srting#p=
|
1070
1245
|
|
1071
|
-
|
1246
|
+
=no_create_table= parameter specifies whether to include a statement to create a table in the SQL file, and the
|
1247
|
+
default value is =false= .
|
1072
1248
|
|
1073
|
-
|
1074
|
-
class String
|
1075
|
-
def p
|
1076
|
-
puts self
|
1077
|
-
end
|
1078
|
-
end
|
1079
|
-
#+end_example
|
1249
|
+
*** Plot
|
1080
1250
|
|
1251
|
+
Arql integrates the youplot library of Ruby and adds some methods to Array that can be used to draw charts:
|
1081
1252
|
|
1082
|
-
|
1253
|
+
+ =barplot=
|
1254
|
+
+ =countplot=
|
1255
|
+
+ =histo=
|
1256
|
+
+ =lineplot=
|
1257
|
+
+ =lineplots=
|
1258
|
+
+ =scatter=
|
1259
|
+
+ =density=
|
1260
|
+
+ =boxplot=
|
1083
1261
|
|
1084
|
-
|
1262
|
+
Example:
|
1085
1263
|
|
1086
|
-
|
1087
|
-
on the file extension in the file path.
|
1264
|
+
Count plot:
|
1088
1265
|
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1266
|
+
#+BEGIN_EXAMPLE
|
1267
|
+
ARQL@demo247(main) [44] ❯ Student.pluck(:gender)
|
1268
|
+
=> ["M", "M", "M", "M", "M", "M", "M", "F", "M", "F", "M", "M", "M", "M", "M"]
|
1269
|
+
ARQL@demo247(main) [45] ❯ Student.pluck(:gender).countplot
|
1270
|
+
┌ ┐
|
1271
|
+
M ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 13.0
|
1272
|
+
F ┤■■■■■ 2.0
|
1273
|
+
└ ┘
|
1274
|
+
#+END_EXAMPLE
|
1094
1275
|
|
1095
|
-
|
1276
|
+
Histo plot:
|
1096
1277
|
|
1097
|
-
|
1278
|
+
#+BEGIN_EXAMPLE
|
1279
|
+
ARQL@jicai.dev(main) [18] ❯ Order.last(20).pluck(:order_sum)
|
1280
|
+
=> [0.21876e5, 0.336571e5, 0.1934e5, 0.966239e4, 0.38748e3, 0.31092e4, 0.483e5, 0.445121e5, 0.1305e4, 0.2296e6, 0.943e5, 0.352e4, 0.3756e5, 0.323781e5, 0.7937622e5, 0.982e4, 0.338393e5, 0.316597e5, 0.213678e5, 0.336845e5]
|
1281
|
+
ARQL@jicai.dev(main) [19] ❯ Order.last(20).pluck(:order_sum).histo
|
1282
|
+
┌ ┐
|
1283
|
+
[ 0.0, 50000.0) ┤▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 17
|
1284
|
+
[ 50000.0, 100000.0) ┤▇▇▇▇ 2
|
1285
|
+
[100000.0, 150000.0) ┤ 0
|
1286
|
+
[150000.0, 200000.0) ┤ 0
|
1287
|
+
[200000.0, 250000.0) ┤▇▇ 1
|
1288
|
+
└ ┘
|
1289
|
+
Frequency
|
1098
1290
|
|
1099
|
-
|
1100
|
-
id = ID.long # 生成一个雪花算法 ID
|
1101
|
-
id = ID.uuid # 生成一个 UUID
|
1102
|
-
#+END_EXAMPLE
|
1291
|
+
#+END_EXAMPLE
|
1103
1292
|
|
1104
|
-
|
1293
|
+
*** Ransack
|
1105
1294
|
|
1106
|
-
|
1295
|
+
Arql integrates Ransack:
|
1107
1296
|
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1297
|
+
#+BEGIN_EXAMPLE
|
1298
|
+
Student.ransack(name_cont: 'Tom').result # query students whose name contains 'Tom'
|
1299
|
+
Student.ransack(name_start: 'Tom').result # query students whose name starts with 'Tom'
|
1300
|
+
#+END_EXAMPLE
|
1112
1301
|
|
1113
1302
|
*** Emacs Org Babel Integration
|
1114
1303
|
|
@@ -1131,20 +1320,6 @@
|
|
1131
1320
|
arql -d db/development.sqlite3
|
1132
1321
|
#+END_EXAMPLE
|
1133
1322
|
|
1134
|
-
*** Find fields by name or comment
|
1135
|
-
|
1136
|
-
When we are familiar with a project, we often encounter the following situation: we know the name or comment of a
|
1137
|
-
field, but we do not know the corresponding table name and field name. At this time, we can use the following method
|
1138
|
-
to find:
|
1139
|
-
|
1140
|
-
#+BEGIN_SRC ruby
|
1141
|
-
puts model_classes.flat_map { |m| m.columns.select {|c| c.name =~ /amount/ || c.comment =~ /金额/ }.map {|c| "Table: #{m.table_name}, Column: #{c.name} (#{c.comment})"} }
|
1142
|
-
|
1143
|
-
# 输出:
|
1144
|
-
# Table: order, Column: entry_amount (订单金额)
|
1145
|
-
# Table: sub_order, Column: entry_price (金额)
|
1146
|
-
#+END_SRC
|
1147
|
-
|
1148
1323
|
** Development
|
1149
1324
|
|
1150
1325
|
After checking out the code, run =bin/setup= to install dependencies. You can also run =bin/console= for an
|