Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/prawn-cake/pg_requests
PostgreSQL-specific query builder library
https://github.com/prawn-cake/pg_requests
database postgresql python sql-query
Last synced: 19 days ago
JSON representation
PostgreSQL-specific query builder library
- Host: GitHub
- URL: https://github.com/prawn-cake/pg_requests
- Owner: prawn-cake
- License: mit
- Created: 2016-05-28T07:13:39.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2017-11-05T20:08:52.000Z (about 7 years ago)
- Last Synced: 2024-11-18T04:38:59.160Z (about 2 months ago)
- Topics: database, postgresql, python, sql-query
- Language: Python
- Homepage:
- Size: 47.9 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: Changelog.md
- License: LICENSE
Awesome Lists containing this project
README
pg_requests
========
[![Build Status](https://travis-ci.org/prawn-cake/pg_requests.svg?branch=master)](https://travis-ci.org/prawn-cake/pg_requests)
[![Coverage Status](https://coveralls.io/repos/github/prawn-cake/pg_requests/badge.svg?branch=master)](https://coveralls.io/github/prawn-cake/pg_requests?branch=master)PostgreSQL-specific query builder.
## Why?
In some cases using ORM or well-known frameworks is not applicable when we are
forced to work with database and plain sql directly.It's quite easy to write simple sql queries until it becomes cumbersome:
long multi-line sql queries, wrong arguments evaluation creates risks for sql injections,
building up sql depends on input parameters and extra conditions make manual way unmaintainable and barely checkableThe library provides handy way to build sql queries for PostgreSQL
## Requirements
* python2.7, python3.4+
## Querying
All queries are executed in a safe manner,
i.e every query is a tuple of sql template string and tuple of parameters, e.g
('SELECT * FROM users WHERE ( name = %s )', ('Mr.Robot',))
And this is already prepared query for `psycopg2.cursor` execution, rely on that it also excludes sql-injection chances.**Starting point**
from pg_requests import query_facade as qf### Select
qf.select()\
.fields()\
.filter()#### Example
result_set = qf.select('users')\
.fields('id', 'name')\
.filter(created_at__gt=datetime.now() - timedelta(days=30))\
.order_by('created_at').desc()\
.limit(10)\
.offset(20)\
.execute(cursor).fetchall()##### Q-object
Q-object mimics django Q object and allows to build complex querying conditions (especially OR conditions for WHERE clause)
from pg_requests import Q
...
users = qf.select('users')\
.filter(Q(name='Mr.Robot') | Q(login='anonymous'))\
.filter(Q(name='John'))
.execute(cursor)
.fetchall()#### Complex conditions
#### Join
# USING syntax
qf.select('users').join('customers', using=('id', )).execute(cursor)
# The following SQL will be executed
SELECT * FROM users INNER JOIN customers USING (id)
# Using different join types
from pg_requests.operators import JOIN
qf.select('users')\
.join('customers', join_type=JOIN.RIGHT_OUTER, using=('id', ))\
.filter(users__name='Mr.Robot')
.execute(cursor)
# Query value
('SELECT * FROM users RIGHT OUTER JOIN customers USING (id) WHERE ( users.name = %s )', ('Mr.Robot',))###### {table}.{field} Key evaluation
To use explicit form *{table}.{field}* you have to use the syntax:
qf.select('users')\
.join('customers', using=('id', )).filter(users__name='Mr.Robot').execute(cursor)#### Functions
##### Aggregation
...
from pg_requests.functions import fn
qf.select('users').fields(fn.COUNT('*')).filter(name='Mr.Robot')
# Query tuple
('SELECT COUNT(*) FROM users WHERE ( name = %s )', ('Mr.Robot',))##### Calling stored procedures (user-defined database functions)
qf.call_fn('my_user_function', args=(1, 'str value', False))
# Query tuple
('SELECT * FROM my_user_function(%s, %s, %s)', (1, 'str value', False))### Insert
**IMPORTANT: all the mutations require connection commit (or autocommit=True) option (fair for psycopg2 cursors)**
#### Example
qf.insert('users').data(name='x', login='y').returning('id').execute(cursor)
# NOTE: If psycopg2 is used and no autocommit=True is enabled
cursor.connection.commit()
### Update#### Example
# Basic example
qf.update('users').data(users='Mr.Robot').filter(id=1).execute(cursor)
# Update from foreign table (with JOIN)
qf.update('users')._from('customers').data(users__value='customers.value')\
.filter(users__id='customers.id').execute(cursor)
# NOTE: If psycopg2 is used and no autocommit=True is enabled
cursor.connection.commit()
**NOTE:** In the last example we use {table}__{field} syntax key evaluation##### F-object
F-object is used to refer directly to a table field, useful for example for increments, i.e such SQL update query
UPDATE users
SET count = count + 1
WHERE name = 'John';Can be implemented as
from pg_requests import F
...
qf.update('users').data(count=F('count') + 1).filter(name='John').execute(cursor)
cursor.connection.commit()### Delete
Not implemented