Skip to content

Commit 4efcd1c

Browse files
committed
records: Add example about program use
1 parent c2b20b4 commit 4efcd1c

File tree

9 files changed

+209
-1
lines changed

9 files changed

+209
-1
lines changed

.github/dependabot.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ updates:
100100
schedule:
101101
interval: "daily"
102102

103+
- directory: "/application/records"
104+
package-ecosystem: "pip"
105+
schedule:
106+
interval: "daily"
107+
103108
# Frameworks.
104109

105110
- directory: "/framework/dbt/basic"
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: records (application)
2+
3+
on:
4+
pull_request:
5+
branches: ~
6+
paths:
7+
- '.github/workflows/application-records.yml'
8+
- 'application/records/**'
9+
- '/requirements.txt'
10+
push:
11+
branches: [ main ]
12+
paths:
13+
- '.github/workflows/application-records.yml'
14+
- 'application/records/**'
15+
- '/requirements.txt'
16+
17+
# Allow job to be triggered manually.
18+
workflow_dispatch:
19+
20+
# Run job each night after CrateDB nightly has been published.
21+
schedule:
22+
- cron: '0 3 * * *'
23+
24+
# Cancel in-progress jobs when pushing to the same branch.
25+
concurrency:
26+
cancel-in-progress: true
27+
group: ${{ github.workflow }}-${{ github.ref }}
28+
29+
jobs:
30+
test:
31+
name: "
32+
Python: ${{ matrix.python-version }}
33+
CrateDB: ${{ matrix.cratedb-version }}
34+
on ${{ matrix.os }}"
35+
runs-on: ${{ matrix.os }}
36+
strategy:
37+
fail-fast: false
38+
matrix:
39+
os: [ 'ubuntu-latest' ]
40+
python-version: [ '3.9', '3.13' ]
41+
cratedb-version: [ 'nightly' ]
42+
43+
services:
44+
cratedb:
45+
image: crate/crate:${{ matrix.cratedb-version }}
46+
ports:
47+
- 4200:4200
48+
- 5432:5432
49+
env:
50+
CRATE_HEAP_SIZE: 4g
51+
52+
steps:
53+
54+
- name: Acquire sources
55+
uses: actions/checkout@v4
56+
57+
- name: Set up Python
58+
uses: actions/setup-python@v5
59+
with:
60+
python-version: ${{ matrix.python-version }}
61+
architecture: x64
62+
cache: 'pip'
63+
cache-dependency-path: |
64+
requirements.txt
65+
application/records/requirements.txt
66+
application/records/requirements-dev.txt
67+
68+
- name: Install utilities
69+
run: |
70+
pip install -r requirements.txt
71+
72+
- name: Validate application/records
73+
run: |
74+
ngr test --accept-no-venv application/records

.github/workflows/framework-records.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: records
1+
name: records (framework)
22

33
on:
44
pull_request:

application/records/README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Verify the `records` program with CrateDB
2+
3+
Records: SQL for Humans™
4+
5+
## About
6+
7+
This folder includes software integration tests for verifying
8+
that the [Records] Python program works well together with [CrateDB].
9+
10+
Records is a very simple, but powerful, library for making raw SQL
11+
queries to most relational databases. It uses [SQLAlchemy].
12+
13+
Records is intended for report-style exports of database queries, and
14+
has not yet been optimized for extremely large data dumps.
15+
16+
## What's Inside
17+
18+
- `example.sh`: A few examples that read CrateDB's `sys.summits` table
19+
using the `records` program. A single example that inserts data into
20+
a column using CrateDB's `OBJECT` column.
21+
22+
## Install
23+
24+
Set up sandbox and install packages.
25+
```bash
26+
pip install uv
27+
uv venv .venv
28+
source .venv/bin/activate
29+
uv pip install -r requirements.txt
30+
```
31+
32+
## Synopsis
33+
Install packages.
34+
```shell
35+
pip install --upgrade records sqlalchemy-cratedb
36+
```
37+
Define database connection URL, suitable for CrateDB on localhost.
38+
For CrateDB Cloud, use `crate://<username>:<password>@<host>`.
39+
```shell
40+
export DATABASE_URL="crate://"
41+
```
42+
Invoke query.
43+
```shell
44+
records "SELECT * FROM sys.summits WHERE region ILIKE :region" region="ortler%"
45+
```
46+
47+
## Tests
48+
49+
Run integration tests.
50+
```bash
51+
sh test.sh
52+
```
53+
54+
55+
[CrateDB]: https://cratedb.com/database
56+
[Records]: https://pypi.org/project/records/
57+
[SQLAlchemy]: https://www.sqlalchemy.org/

application/records/example.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env sh
2+
3+
# Using `records` with CrateDB: Basic usage.
4+
#
5+
# pip install --upgrade records sqlalchemy-cratedb
6+
#
7+
# A few basic operations using the `records` program with CrateDB.
8+
#
9+
# - https://pypi.org/project/records/
10+
11+
# Define database connection URL, suitable for CrateDB on localhost.
12+
# For CrateDB Cloud, use `crate://<username>:<password>@<host>`.
13+
export DATABASE_URL="crate://"
14+
15+
# Basic query, tabular output.
16+
records "SELECT * FROM sys.summits ORDER BY height DESC LIMIT 3"
17+
18+
# Query with parameters.
19+
records "SELECT * FROM sys.summits WHERE region ILIKE :region" region="ortler%"
20+
21+
# Export data.
22+
# Supported formats: csv tsv json yaml html xls xlsx dbf latex ods
23+
records "SELECT * FROM sys.summits ORDER BY height DESC LIMIT 3" csv
24+
records "SELECT * FROM sys.summits ORDER BY height DESC LIMIT 3" json
25+
records "SELECT * FROM sys.summits LIMIT 42" html > "${TMPDIR}/sys_summits.html"
26+
records "SELECT * FROM sys.summits LIMIT 42" ods > "${TMPDIR}/sys_summits.ods"
27+
records "SELECT * FROM sys.summits LIMIT 42" xlsx > "${TMPDIR}/sys_summits.xlsx"
28+
29+
# Insert data.
30+
records "DROP TABLE IF EXISTS testdrive.example"
31+
records "CREATE TABLE testdrive.example (data OBJECT(DYNAMIC))"
32+
records "INSERT INTO testdrive.example (data) VALUES (:data)" data='{"temperature": 42.42, "humidity": 84.84}'
33+
records "REFRESH TABLE testdrive.example"
34+
records "SELECT * FROM testdrive.example"

application/records/pyproject.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[tool.pytest.ini_options]
2+
minversion = "2.0"
3+
addopts = """
4+
-rfEX -p pytester --strict-markers --verbosity=3
5+
--capture=no
6+
"""
7+
log_level = "DEBUG"
8+
log_cli_level = "DEBUG"
9+
testpaths = ["*.py"]
10+
xfail_strict = true
11+
markers = [
12+
]
13+
14+
15+
[tool.coverage.run]
16+
branch = false
17+
omit = [
18+
"test*",
19+
]
20+
21+
[tool.coverage.report]
22+
fail_under = 0
23+
show_missing = true
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest<9

application/records/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
records<0.7
2+
sqlalchemy-cratedb<0.41
3+
tablib[ods]

application/records/test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import shlex
2+
import subprocess
3+
import pytest
4+
5+
6+
def run(command: str):
7+
subprocess.check_call(shlex.split(command))
8+
9+
10+
def test_example():
11+
run("sh example.sh")

0 commit comments

Comments
 (0)