t-sql 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {t_sql-0.1.0 → t_sql-0.1.2}/LICENSE +2 -2
- t_sql-0.1.2/PKG-INFO +160 -0
- t_sql-0.1.2/README.md +151 -0
- t_sql-0.1.2/pyproject.toml +15 -0
- t_sql-0.1.2/t_sql.egg-info/PKG-INFO +160 -0
- {t_sql-0.1.0 → t_sql-0.1.2}/t_sql.egg-info/SOURCES.txt +6 -2
- t_sql-0.1.2/tests/test_asyncpg_integration.py +269 -0
- t_sql-0.1.2/tests/test_different_object_types.py +18 -0
- t_sql-0.1.2/tests/test_escaped.py +168 -0
- t_sql-0.1.2/tests/test_helper_functions.py +102 -0
- t_sql-0.1.2/tests/test_styles.py +104 -0
- t_sql-0.1.2/tests/test_tsql.py +116 -0
- t_sql-0.1.2/tsql/__init__.py +223 -0
- t_sql-0.1.2/tsql/styles.py +90 -0
- t_sql-0.1.0/PKG-INFO +0 -96
- t_sql-0.1.0/README.md +0 -72
- t_sql-0.1.0/pyproject.toml +0 -41
- t_sql-0.1.0/t_sql.egg-info/PKG-INFO +0 -96
- t_sql-0.1.0/t_sql.egg-info/requires.txt +0 -5
- t_sql-0.1.0/tests/test_tsql.py +0 -18
- t_sql-0.1.0/tsql/__init__.py +0 -7
- t_sql-0.1.0/tsql/tsql.py +0 -30
- {t_sql-0.1.0 → t_sql-0.1.2}/setup.cfg +0 -0
- {t_sql-0.1.0 → t_sql-0.1.2}/t_sql.egg-info/dependency_links.txt +0 -0
- {t_sql-0.1.0 → t_sql-0.1.2}/t_sql.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025
|
|
3
|
+
Copyright (c) 2025 Nick Humrich
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
21
|
+
SOFTWARE.
|
t_sql-0.1.2/PKG-INFO
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: t-sql
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Safe SQL. SQL queries for python t-strings (PEP 750)
|
|
5
|
+
Requires-Python: >=3.14
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Dynamic: license-file
|
|
9
|
+
|
|
10
|
+
# tsql
|
|
11
|
+
|
|
12
|
+
A lightweight SQL templating library that leverages Python 3.14's t-strings (PEP 750).
|
|
13
|
+
|
|
14
|
+
TSQL provides a safe way to write SQL queries using Python's template strings (t-strings) while preventing SQL injection attacks through multiple parameter styling options.
|
|
15
|
+
|
|
16
|
+
## ⚠️ Python Version Requirement
|
|
17
|
+
This library requires Python 3.14b1 or newer.
|
|
18
|
+
|
|
19
|
+
TSQL is built specifically to take advantage of the new t-string feature introduced in PEP 750, which is only available in Python 3.14+.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Parameter Styles
|
|
23
|
+
|
|
24
|
+
- **QMARK** (default): Uses `?` placeholders
|
|
25
|
+
- **NUMERIC**: Uses `:1`, `:2`, etc. placeholders
|
|
26
|
+
- **NAMED**: Uses `:name` placeholders
|
|
27
|
+
- **FORMAT**: Uses `%s` placeholders
|
|
28
|
+
- **PYFORMAT**: Uses `%(name)s` placeholders
|
|
29
|
+
- **NUMERIC_DOLLAR**: Uses `$1`, `$2`, etc. (PostgreSQL native)
|
|
30
|
+
- **ESCAPED**: Escapes values directly into SQL (no parameters)
|
|
31
|
+
|
|
32
|
+
## Examples:
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
|
|
36
|
+
# Basic usage with different parameter styles
|
|
37
|
+
import tsql
|
|
38
|
+
import tsql.styles
|
|
39
|
+
|
|
40
|
+
name = 'billy'
|
|
41
|
+
query = t'select * from users where name={name}'
|
|
42
|
+
|
|
43
|
+
# Default QMARK style
|
|
44
|
+
print(tsql.render(query))
|
|
45
|
+
# ('select * from users where name = ?', ['billy'])
|
|
46
|
+
|
|
47
|
+
# PostgreSQL native style
|
|
48
|
+
print(tsql.render(query, style=tsql.styles.NUMERIC_DOLLAR))
|
|
49
|
+
# ('select * from users where name = $1', ['billy'])
|
|
50
|
+
|
|
51
|
+
# ESCAPED style (no parameters)
|
|
52
|
+
print(tsql.render(query, style=tsql.styles.ESCAPED))
|
|
53
|
+
# ("select * from users where name = 'billy'", [])
|
|
54
|
+
|
|
55
|
+
# SQL injection prevention
|
|
56
|
+
name = "billy ' and 1=1 --"
|
|
57
|
+
print(tsql.render(query, style=tsql.styles.ESCAPED))
|
|
58
|
+
# ("select * from users where name = 'billy '' and 1=1 --'", [])
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Format-spec helpers
|
|
63
|
+
|
|
64
|
+
There are some built-in format spec helpers that can change the way some
|
|
65
|
+
parts of the library work.
|
|
66
|
+
|
|
67
|
+
### Literal
|
|
68
|
+
One common example is you may want to set the name
|
|
69
|
+
of a column dynamically. By using the `literal` format spec, the value will
|
|
70
|
+
be sanitized against a valid literal and put straight into the sql query since
|
|
71
|
+
you cannot parameterize that part of a query, example:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
query = t'select * from {table:literal} where {col:literal}={val}'
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
or, a full example:
|
|
78
|
+
```python
|
|
79
|
+
|
|
80
|
+
# with a like clause
|
|
81
|
+
min_age = 30
|
|
82
|
+
search_column = "name"
|
|
83
|
+
pattern = "O'Brien"
|
|
84
|
+
is_active = True
|
|
85
|
+
tsql.render(t"SELECT * FROM test_users WHERE age >= {min_age} AND {search_column:literal} LIKE '%' || {pattern} || '%' AND active = {is_active}")
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### unsafe
|
|
89
|
+
You may want to do advanced things that may otherwise be considered unsfe.
|
|
90
|
+
This is okay if you can be sure that a user is not providing input. Like maybe
|
|
91
|
+
you care storing a query for some reason.
|
|
92
|
+
As per the name, this can open you up to sql injection and should be used with
|
|
93
|
+
extreme caution.
|
|
94
|
+
You can use the "unsafe" format spec for these
|
|
95
|
+
cases:
|
|
96
|
+
```python
|
|
97
|
+
dynamic_where = input('type where clause')
|
|
98
|
+
tsql.render(f"SELECT * FROM users WHERE {dynamic_where:unsafe}")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### as_values
|
|
102
|
+
|
|
103
|
+
The spec `:as_values` formats a dictionary into the format:
|
|
104
|
+
`(key1, key2, ...) VALUES (value1, value2, ...)` for uses in insert statements.
|
|
105
|
+
|
|
106
|
+
### traditional format_spec
|
|
107
|
+
|
|
108
|
+
All other format specs should be handled as they would in a normal f-string.
|
|
109
|
+
|
|
110
|
+
## Included helper methods
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
# select
|
|
114
|
+
tsql.select('table', 'abc123')
|
|
115
|
+
# SELECT * FROM table WHERE id='abc123'
|
|
116
|
+
|
|
117
|
+
# select with multiple ids and specific columns
|
|
118
|
+
tsql.select('users', ['abc123', 'def456'], columns=['name', 'age'])
|
|
119
|
+
# SELECT name, age FROM users WHERE id in ('abc123', 'def456')
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# t_join (joins multiple t-strings together like .join on a str)
|
|
123
|
+
tsql.t_join(t" ", [t"hello", t"there"])
|
|
124
|
+
# t"hello there"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# insert
|
|
128
|
+
table = 'users'
|
|
129
|
+
values = {'id': 'abc123', 'name': 'bob', 'email': 'bob@example.com'}
|
|
130
|
+
tsql.insert(table, values)
|
|
131
|
+
# INSERT INTO users (id, name, email) VALUES ('abc123', 'bob', 'bob@example.com')
|
|
132
|
+
|
|
133
|
+
# update values on a single row
|
|
134
|
+
table = 'users'
|
|
135
|
+
values = {'name': 'joe', 'email': 'joe@example.com'}
|
|
136
|
+
tsql.update(table, values, id='abc123')
|
|
137
|
+
# UPDATE users SET name='joe', email='joe@example.com' WHERE id='abc123'
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
# Note on usage
|
|
141
|
+
|
|
142
|
+
This library should ideally be used inside middleware or library code
|
|
143
|
+
right before making an actual query. It can be used to enforce
|
|
144
|
+
using t-strings and prevent using raw strings.
|
|
145
|
+
|
|
146
|
+
For example:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
from string.templatelib import Template
|
|
150
|
+
|
|
151
|
+
import tsql
|
|
152
|
+
|
|
153
|
+
def execute_sql_query(query):
|
|
154
|
+
if not isinstance(query, Template):
|
|
155
|
+
raise TypeError('Cannot make a query without using t-strings')
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
return sql_engine.execute(*tsql.render(query))
|
|
159
|
+
|
|
160
|
+
```
|
t_sql-0.1.2/README.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# tsql
|
|
2
|
+
|
|
3
|
+
A lightweight SQL templating library that leverages Python 3.14's t-strings (PEP 750).
|
|
4
|
+
|
|
5
|
+
TSQL provides a safe way to write SQL queries using Python's template strings (t-strings) while preventing SQL injection attacks through multiple parameter styling options.
|
|
6
|
+
|
|
7
|
+
## ⚠️ Python Version Requirement
|
|
8
|
+
This library requires Python 3.14b1 or newer.
|
|
9
|
+
|
|
10
|
+
TSQL is built specifically to take advantage of the new t-string feature introduced in PEP 750, which is only available in Python 3.14+.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## Parameter Styles
|
|
14
|
+
|
|
15
|
+
- **QMARK** (default): Uses `?` placeholders
|
|
16
|
+
- **NUMERIC**: Uses `:1`, `:2`, etc. placeholders
|
|
17
|
+
- **NAMED**: Uses `:name` placeholders
|
|
18
|
+
- **FORMAT**: Uses `%s` placeholders
|
|
19
|
+
- **PYFORMAT**: Uses `%(name)s` placeholders
|
|
20
|
+
- **NUMERIC_DOLLAR**: Uses `$1`, `$2`, etc. (PostgreSQL native)
|
|
21
|
+
- **ESCAPED**: Escapes values directly into SQL (no parameters)
|
|
22
|
+
|
|
23
|
+
## Examples:
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
|
|
27
|
+
# Basic usage with different parameter styles
|
|
28
|
+
import tsql
|
|
29
|
+
import tsql.styles
|
|
30
|
+
|
|
31
|
+
name = 'billy'
|
|
32
|
+
query = t'select * from users where name={name}'
|
|
33
|
+
|
|
34
|
+
# Default QMARK style
|
|
35
|
+
print(tsql.render(query))
|
|
36
|
+
# ('select * from users where name = ?', ['billy'])
|
|
37
|
+
|
|
38
|
+
# PostgreSQL native style
|
|
39
|
+
print(tsql.render(query, style=tsql.styles.NUMERIC_DOLLAR))
|
|
40
|
+
# ('select * from users where name = $1', ['billy'])
|
|
41
|
+
|
|
42
|
+
# ESCAPED style (no parameters)
|
|
43
|
+
print(tsql.render(query, style=tsql.styles.ESCAPED))
|
|
44
|
+
# ("select * from users where name = 'billy'", [])
|
|
45
|
+
|
|
46
|
+
# SQL injection prevention
|
|
47
|
+
name = "billy ' and 1=1 --"
|
|
48
|
+
print(tsql.render(query, style=tsql.styles.ESCAPED))
|
|
49
|
+
# ("select * from users where name = 'billy '' and 1=1 --'", [])
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Format-spec helpers
|
|
54
|
+
|
|
55
|
+
There are some built-in format spec helpers that can change the way some
|
|
56
|
+
parts of the library work.
|
|
57
|
+
|
|
58
|
+
### Literal
|
|
59
|
+
One common example is you may want to set the name
|
|
60
|
+
of a column dynamically. By using the `literal` format spec, the value will
|
|
61
|
+
be sanitized against a valid literal and put straight into the sql query since
|
|
62
|
+
you cannot parameterize that part of a query, example:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
query = t'select * from {table:literal} where {col:literal}={val}'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
or, a full example:
|
|
69
|
+
```python
|
|
70
|
+
|
|
71
|
+
# with a like clause
|
|
72
|
+
min_age = 30
|
|
73
|
+
search_column = "name"
|
|
74
|
+
pattern = "O'Brien"
|
|
75
|
+
is_active = True
|
|
76
|
+
tsql.render(t"SELECT * FROM test_users WHERE age >= {min_age} AND {search_column:literal} LIKE '%' || {pattern} || '%' AND active = {is_active}")
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### unsafe
|
|
80
|
+
You may want to do advanced things that may otherwise be considered unsfe.
|
|
81
|
+
This is okay if you can be sure that a user is not providing input. Like maybe
|
|
82
|
+
you care storing a query for some reason.
|
|
83
|
+
As per the name, this can open you up to sql injection and should be used with
|
|
84
|
+
extreme caution.
|
|
85
|
+
You can use the "unsafe" format spec for these
|
|
86
|
+
cases:
|
|
87
|
+
```python
|
|
88
|
+
dynamic_where = input('type where clause')
|
|
89
|
+
tsql.render(f"SELECT * FROM users WHERE {dynamic_where:unsafe}")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### as_values
|
|
93
|
+
|
|
94
|
+
The spec `:as_values` formats a dictionary into the format:
|
|
95
|
+
`(key1, key2, ...) VALUES (value1, value2, ...)` for uses in insert statements.
|
|
96
|
+
|
|
97
|
+
### traditional format_spec
|
|
98
|
+
|
|
99
|
+
All other format specs should be handled as they would in a normal f-string.
|
|
100
|
+
|
|
101
|
+
## Included helper methods
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
# select
|
|
105
|
+
tsql.select('table', 'abc123')
|
|
106
|
+
# SELECT * FROM table WHERE id='abc123'
|
|
107
|
+
|
|
108
|
+
# select with multiple ids and specific columns
|
|
109
|
+
tsql.select('users', ['abc123', 'def456'], columns=['name', 'age'])
|
|
110
|
+
# SELECT name, age FROM users WHERE id in ('abc123', 'def456')
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# t_join (joins multiple t-strings together like .join on a str)
|
|
114
|
+
tsql.t_join(t" ", [t"hello", t"there"])
|
|
115
|
+
# t"hello there"
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# insert
|
|
119
|
+
table = 'users'
|
|
120
|
+
values = {'id': 'abc123', 'name': 'bob', 'email': 'bob@example.com'}
|
|
121
|
+
tsql.insert(table, values)
|
|
122
|
+
# INSERT INTO users (id, name, email) VALUES ('abc123', 'bob', 'bob@example.com')
|
|
123
|
+
|
|
124
|
+
# update values on a single row
|
|
125
|
+
table = 'users'
|
|
126
|
+
values = {'name': 'joe', 'email': 'joe@example.com'}
|
|
127
|
+
tsql.update(table, values, id='abc123')
|
|
128
|
+
# UPDATE users SET name='joe', email='joe@example.com' WHERE id='abc123'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
# Note on usage
|
|
132
|
+
|
|
133
|
+
This library should ideally be used inside middleware or library code
|
|
134
|
+
right before making an actual query. It can be used to enforce
|
|
135
|
+
using t-strings and prevent using raw strings.
|
|
136
|
+
|
|
137
|
+
For example:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
from string.templatelib import Template
|
|
141
|
+
|
|
142
|
+
import tsql
|
|
143
|
+
|
|
144
|
+
def execute_sql_query(query):
|
|
145
|
+
if not isinstance(query, Template):
|
|
146
|
+
raise TypeError('Cannot make a query without using t-strings')
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
return sql_engine.execute(*tsql.render(query))
|
|
150
|
+
|
|
151
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "t-sql"
|
|
3
|
+
version = "0.1.2"
|
|
4
|
+
description = "Safe SQL. SQL queries for python t-strings (PEP 750)"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.14"
|
|
7
|
+
dependencies = []
|
|
8
|
+
|
|
9
|
+
[dependency-groups]
|
|
10
|
+
dev = [
|
|
11
|
+
"anyio>=4.9.0",
|
|
12
|
+
"asyncpg>=0.30.0",
|
|
13
|
+
"pytest>=8.3.5",
|
|
14
|
+
"pytest-asyncio>=0.24.0",
|
|
15
|
+
]
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: t-sql
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Safe SQL. SQL queries for python t-strings (PEP 750)
|
|
5
|
+
Requires-Python: >=3.14
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Dynamic: license-file
|
|
9
|
+
|
|
10
|
+
# tsql
|
|
11
|
+
|
|
12
|
+
A lightweight SQL templating library that leverages Python 3.14's t-strings (PEP 750).
|
|
13
|
+
|
|
14
|
+
TSQL provides a safe way to write SQL queries using Python's template strings (t-strings) while preventing SQL injection attacks through multiple parameter styling options.
|
|
15
|
+
|
|
16
|
+
## ⚠️ Python Version Requirement
|
|
17
|
+
This library requires Python 3.14b1 or newer.
|
|
18
|
+
|
|
19
|
+
TSQL is built specifically to take advantage of the new t-string feature introduced in PEP 750, which is only available in Python 3.14+.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Parameter Styles
|
|
23
|
+
|
|
24
|
+
- **QMARK** (default): Uses `?` placeholders
|
|
25
|
+
- **NUMERIC**: Uses `:1`, `:2`, etc. placeholders
|
|
26
|
+
- **NAMED**: Uses `:name` placeholders
|
|
27
|
+
- **FORMAT**: Uses `%s` placeholders
|
|
28
|
+
- **PYFORMAT**: Uses `%(name)s` placeholders
|
|
29
|
+
- **NUMERIC_DOLLAR**: Uses `$1`, `$2`, etc. (PostgreSQL native)
|
|
30
|
+
- **ESCAPED**: Escapes values directly into SQL (no parameters)
|
|
31
|
+
|
|
32
|
+
## Examples:
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
|
|
36
|
+
# Basic usage with different parameter styles
|
|
37
|
+
import tsql
|
|
38
|
+
import tsql.styles
|
|
39
|
+
|
|
40
|
+
name = 'billy'
|
|
41
|
+
query = t'select * from users where name={name}'
|
|
42
|
+
|
|
43
|
+
# Default QMARK style
|
|
44
|
+
print(tsql.render(query))
|
|
45
|
+
# ('select * from users where name = ?', ['billy'])
|
|
46
|
+
|
|
47
|
+
# PostgreSQL native style
|
|
48
|
+
print(tsql.render(query, style=tsql.styles.NUMERIC_DOLLAR))
|
|
49
|
+
# ('select * from users where name = $1', ['billy'])
|
|
50
|
+
|
|
51
|
+
# ESCAPED style (no parameters)
|
|
52
|
+
print(tsql.render(query, style=tsql.styles.ESCAPED))
|
|
53
|
+
# ("select * from users where name = 'billy'", [])
|
|
54
|
+
|
|
55
|
+
# SQL injection prevention
|
|
56
|
+
name = "billy ' and 1=1 --"
|
|
57
|
+
print(tsql.render(query, style=tsql.styles.ESCAPED))
|
|
58
|
+
# ("select * from users where name = 'billy '' and 1=1 --'", [])
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Format-spec helpers
|
|
63
|
+
|
|
64
|
+
There are some built-in format spec helpers that can change the way some
|
|
65
|
+
parts of the library work.
|
|
66
|
+
|
|
67
|
+
### Literal
|
|
68
|
+
One common example is you may want to set the name
|
|
69
|
+
of a column dynamically. By using the `literal` format spec, the value will
|
|
70
|
+
be sanitized against a valid literal and put straight into the sql query since
|
|
71
|
+
you cannot parameterize that part of a query, example:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
query = t'select * from {table:literal} where {col:literal}={val}'
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
or, a full example:
|
|
78
|
+
```python
|
|
79
|
+
|
|
80
|
+
# with a like clause
|
|
81
|
+
min_age = 30
|
|
82
|
+
search_column = "name"
|
|
83
|
+
pattern = "O'Brien"
|
|
84
|
+
is_active = True
|
|
85
|
+
tsql.render(t"SELECT * FROM test_users WHERE age >= {min_age} AND {search_column:literal} LIKE '%' || {pattern} || '%' AND active = {is_active}")
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### unsafe
|
|
89
|
+
You may want to do advanced things that may otherwise be considered unsfe.
|
|
90
|
+
This is okay if you can be sure that a user is not providing input. Like maybe
|
|
91
|
+
you care storing a query for some reason.
|
|
92
|
+
As per the name, this can open you up to sql injection and should be used with
|
|
93
|
+
extreme caution.
|
|
94
|
+
You can use the "unsafe" format spec for these
|
|
95
|
+
cases:
|
|
96
|
+
```python
|
|
97
|
+
dynamic_where = input('type where clause')
|
|
98
|
+
tsql.render(f"SELECT * FROM users WHERE {dynamic_where:unsafe}")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### as_values
|
|
102
|
+
|
|
103
|
+
The spec `:as_values` formats a dictionary into the format:
|
|
104
|
+
`(key1, key2, ...) VALUES (value1, value2, ...)` for uses in insert statements.
|
|
105
|
+
|
|
106
|
+
### traditional format_spec
|
|
107
|
+
|
|
108
|
+
All other format specs should be handled as they would in a normal f-string.
|
|
109
|
+
|
|
110
|
+
## Included helper methods
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
# select
|
|
114
|
+
tsql.select('table', 'abc123')
|
|
115
|
+
# SELECT * FROM table WHERE id='abc123'
|
|
116
|
+
|
|
117
|
+
# select with multiple ids and specific columns
|
|
118
|
+
tsql.select('users', ['abc123', 'def456'], columns=['name', 'age'])
|
|
119
|
+
# SELECT name, age FROM users WHERE id in ('abc123', 'def456')
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# t_join (joins multiple t-strings together like .join on a str)
|
|
123
|
+
tsql.t_join(t" ", [t"hello", t"there"])
|
|
124
|
+
# t"hello there"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# insert
|
|
128
|
+
table = 'users'
|
|
129
|
+
values = {'id': 'abc123', 'name': 'bob', 'email': 'bob@example.com'}
|
|
130
|
+
tsql.insert(table, values)
|
|
131
|
+
# INSERT INTO users (id, name, email) VALUES ('abc123', 'bob', 'bob@example.com')
|
|
132
|
+
|
|
133
|
+
# update values on a single row
|
|
134
|
+
table = 'users'
|
|
135
|
+
values = {'name': 'joe', 'email': 'joe@example.com'}
|
|
136
|
+
tsql.update(table, values, id='abc123')
|
|
137
|
+
# UPDATE users SET name='joe', email='joe@example.com' WHERE id='abc123'
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
# Note on usage
|
|
141
|
+
|
|
142
|
+
This library should ideally be used inside middleware or library code
|
|
143
|
+
right before making an actual query. It can be used to enforce
|
|
144
|
+
using t-strings and prevent using raw strings.
|
|
145
|
+
|
|
146
|
+
For example:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
from string.templatelib import Template
|
|
150
|
+
|
|
151
|
+
import tsql
|
|
152
|
+
|
|
153
|
+
def execute_sql_query(query):
|
|
154
|
+
if not isinstance(query, Template):
|
|
155
|
+
raise TypeError('Cannot make a query without using t-strings')
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
return sql_engine.execute(*tsql.render(query))
|
|
159
|
+
|
|
160
|
+
```
|
|
@@ -4,8 +4,12 @@ pyproject.toml
|
|
|
4
4
|
t_sql.egg-info/PKG-INFO
|
|
5
5
|
t_sql.egg-info/SOURCES.txt
|
|
6
6
|
t_sql.egg-info/dependency_links.txt
|
|
7
|
-
t_sql.egg-info/requires.txt
|
|
8
7
|
t_sql.egg-info/top_level.txt
|
|
8
|
+
tests/test_asyncpg_integration.py
|
|
9
|
+
tests/test_different_object_types.py
|
|
10
|
+
tests/test_escaped.py
|
|
11
|
+
tests/test_helper_functions.py
|
|
12
|
+
tests/test_styles.py
|
|
9
13
|
tests/test_tsql.py
|
|
10
14
|
tsql/__init__.py
|
|
11
|
-
tsql/
|
|
15
|
+
tsql/styles.py
|