Update README.md

This commit is contained in:
ge 2023-07-19 09:46:12 +03:00
parent 40f121ad84
commit 0a24ded7ec

132
README.md
View File

@ -1,20 +1,20 @@
```
____ _ __
/ __ \__ __(_)____/ /_____ _____
/ / / / / / / / ___/ //_/ _ \/ ___/
/ /_/ / /_/ / / /__/ ,< / __/ /
\___\_\__,_/_/\___/_/|_|\___/_/
```
<img width="320px" src="logo.svg"/>
**Quicker** is a pythonic tool for querying databases.
**Quicker** is a pythonic 🐍 tool for querying databases.
Quicker wraps Python bindings on DBMS libraries:
Quicker wraps popular Python libraries:
- `mysqlclient` for MySQL.
- `psycopg2` for PostgreSQL.
- `sqlite` from Python standard library for SQLite (not implemented yet).
Connection parameters will passed to "backend" module as is.
# Why is it needed?
Briefly — just make queries without bothering to learn the abstractions of the library.
At work, I periodically have to make queries to different databases and then somehow process the information. I am not an analyst and Quicker is not intended for analysts. The main use of the library is to quickly execute raw SQL queries into the database. You may want to do this entirely in the Python interactive shell. Quicker interface is as simple as possible, thanks to which lazy system administrators can now effortlessly extract data from the database.
Of course, this library **should not be used in production**. This is just a small assistant in routine tasks.
# Installation
@ -24,30 +24,32 @@ pip install git+https://git.nxhs.cloud/ge/quicker
# Usage
`Connection` is context manages and must be used with `with` keyword. `Connection` returns `Query` callable object. `Query` can be called in this ways:
Quicker uses a context manager. All that is needed for work is to pass connection parameters to object and write the queries themselves. See MySQL example:
```python
with Connection(**config) as db:
db.execute("sql query here...")
db.query("sql query here...") # query is alias for exec()
from quicker import Connection
# Query is callable and you can also do this:
with Connection(**config) as query:
query("sql query here...")
with Connection(provider='mysql', read_default_file='~/.my.cnf') as query:
users = query("SELECT * FROM `users` WHERE admin = 'N'")
```
`Query` cannot be called itself, you must use `Connection` to correctly initialise `Query` object. Available methods and properties:
`Connection` object initialises `Query` callable object for interacting with cursor. You can use `query("sql there..")` or `query.execute("sql...")` syntax. There are the same.
- `query()`, `execute()`. Execute SQL. There is You can use here this syntax: `query('SELECT * FROM users WHERE id = %s', (15,))`.
`Query` object methods and properties:
- `query()`, `execute()`. Execute SQL. There is you can use here this syntax: `query('SELECT * FROM users WHERE id = %s', (15,))`.
- `commit()`. Write changes into database.
- `cursor`. Access cursor object directly.
- `connection`. Access connection object directly.
Full example:
You don't need to commit to the database, Quicker will do it for you, but if you need to, you can commit manually calling `query.commit()`. You can also turn off automatic commit when creating a `Connection` object — pass it the argument `commit=Fasle`.
That's not all — Quicker converts the received data into a list of dictionaries. The list will be empty if nothing was found for the query. If the request does not imply a response, `None` will be returned.
## MySQL example
```python
import json
from quicker import Connection
@ -61,58 +63,86 @@ config = {
}
with Connection(**config) as query:
users = query("SELECT * FROM `users`")
query(
"""
CREATE TABLE IF NOT EXISTS users (
id int AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
"""
)
query(
"INSERT INTO users VALUES (NULL, %s, %s, current_timestamp)",
('john', 'john@exmpl.org',)
)
query.commit()
users = query("SELECT * FROM users")
print(json.dumps(users, indent=4))
print('ID\t NAME\t EMAIL')
for user in users:
print(user['id'], '\t', user['name'], '\t', user['email'])
```
`users` will presented as list of dicts:
## PostgreSQL example
```python
[
{
'id': 1,
'name': 'test',
'email': 'noreply@localhost'
},
{
'id': 2,
'name': 'user1',
'email': 'my@example.com'
}
]
```
import logging
Changing database:
```python
from quicker import Connection
with Connection(provider='mysql', read_default_file='~/.my.cnf') as db:
db.query("INSERT INTO `users` VALUE (3, 'user2', 'user2@example.org')")
logging.basicConfig(level=logging.DEBUG)
config = {
'provider': 'postgres',
'host': '127.0.0.1',
'port': 5432,
'user': 'myuser',
'database': 'mydb',
'password': 'example',
}
with Connection(**config) as query:
query(
"""
CREATE TABLE IF NOT EXISTS users (
id serial PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
"""
)
query(
"INSERT INTO users VALUES ((SELECT MAX(id)+1 FROM users), %s, %s, current_timestamp)",
('phil', 'phil@exmpl.org',)
)
```
Quicker by default make commit after closing context. Set option `commit=False` to disable automatic commit.
For logging add following code:
## Logging
```
For logging add following code in your module:
```python
import logging
logging.basicConfig(level=logging.DEBUG)
```
Direct access to Cursor object:
## Direct access to Cursor object
```
```python
from quicker import Connection, make_list
# config declaration here...
with Connection(**config) as db:
db.cursor.execute('SELECT `id`, `name`, `email` FROM `users` WHERE `name` = %s', ('John',))
db.cursor.execute('SELECT id, name, email FROM users WHERE name = %s', ('John',))
users = db.cursor.fetchall()
# Note: user is tuple! Convert it to list of dicts!
# Note: "users" is tuple! Convert it to list of dicts!
colnames = [desc[0] for desc in db.cursor.description]
users_list = make_list(colnames, users)
```
```