Skip to main content

relations-sql

Module for interacting with Relations and SQL

This is an abstract library used by relations-mysql, relations-postgresql, relations-sqlite, etc. to generate queries specific to those databases.

But folks may find it useful for their usages. So here's some of the main unittests so you get the general idea.

I'll probably switch this to ANSI SQL? I dunno. Not sure how useful that'll be.

import

All the classes are capitalized to prevent collisions with reserved keywords. Plus it looks like actual SQL. So you can do a full import without worries.

from relations_sql import *

select

query = SELECT("*").OPTIONS("FAST").FROM("people").WHERE(stuff__gt="things")

query.generate()
self.assertEqual(query.sql, "SELECT FAST * FROM `people` WHERE `stuff`>%s")
self.assertEqual(query.args, ["things"])

query = SELECT(
    "*"
).FROM(
    people=SELECT(
        "a.b.c"
    ).FROM(
        "d.e"
    )
).WHERE(
    stuff__in=SELECT(
        "f"
    ).FROM(
        "g"
    ).WHERE(
        things__a__0___1____2_____3__gt=5
    )
)

query.generate()
self.assertEqual(query.sql,
    "SELECT * FROM (SELECT `a`.`b`.`c` FROM `d`.`e`) "
    "AS `people` WHERE `stuff` IN "
    "(SELECT `f` FROM `g` WHERE `things`#>>%s>JSON(%s))"
)
self.assertEqual(query.args, ['$."a"[0][-1]."2"."-3"', '5'])

query.GROUP_BY("fee", "fie").HAVING(foe="fum").ORDER_BY("yin", yang=DESC).LIMIT(1, 2)

query.generate()
self.assertEqual(query.sql,
    "SELECT * FROM (SELECT `a`.`b`.`c` FROM `d`.`e`) "
    "AS `people` WHERE `stuff` IN "
    "(SELECT `f` FROM `g` WHERE `things`#>>%s>JSON(%s)) "
    "GROUP BY `fee`,`fie` HAVING `foe`=%s "
    "ORDER BY `yin`,`yang` DESC LIMIT %s,%s"
)
self.assertEqual(query.args, ['$."a"[0][-1]."2"."-3"', '5', 'fum', 1, 2])

insert

query = INSERT("people").VALUES(stuff=1, things=2).VALUES(3, 4)

query.generate()
self.assertEqual(query.sql,"INSERT INTO `people` (`stuff`,`things`) VALUES (%s,%s),(%s,%s)")
self.assertEqual(query.args, [1, 2, 3, 4])

query = INSERT("people").OPTIONS("FAST")
query.SELECT("stuff").FROM("things")

query.generate()
self.assertEqual(query.sql,"INSERT FAST INTO `people` SELECT `stuff` FROM `things`")
self.assertEqual(query.args, [])

query = INSERT("people").VALUES(stuff=1, things=2).VALUES(3, 4)
query.SELECT("stuff").FROM("things")

self.assertRaisesRegex(relations_sql.SQLError, "set VALUES or SELECT but not both", query.generate)

update

query = UPDATE("people").SET(stuff="things").WHERE(things="stuff")
query.OPTIONS("FAST").ORDER_BY("yin", yang=DESC).LIMIT(5)

query.generate()
self.assertEqual(query.sql, "UPDATE FAST `people` SET `stuff`=%s WHERE `things`=%s ORDER BY `yin`,`yang` DESC LIMIT %s")
self.assertEqual(query.args, ["things", "stuff", 5])

query.LIMIT(10)

self.assertRaisesRegex(relations_sql.SQLError, "LIMIT can only be total", query.generate)

delete

query = DELETE("people").WHERE(things="stuff")
query.OPTIONS("FAST").ORDER_BY("yin", yang=DESC).LIMIT(5)

query.generate()
self.assertEqual(query.sql, "DELETE FAST FROM `people` WHERE `things`=%s ORDER BY `yin`,`yang` DESC LIMIT %s")
self.assertEqual(query.args, ["stuff", 5])

query.LIMIT(10)

self.assertRaisesRegex(relations_sql.SQLError, "LIMIT can only be total", query.generate)

inherit

The unittest demonstrate how to abstract through inheritance. Classes know which other classes they'll need through class attributes.

The unittests are where the backticks escaping comes from. It's not a default or anything.

In test_clause.py

class OPTIONS(relations_sql.OPTIONS):

    pass


class FIELDS(relations_sql.FIELDS):

    ARGS = test_expression.FIELD
    KWARG = test_expression.FIELD
    KWARGS = test_expression.AS

In test_query.py

class SELECT(relations_sql.SELECT):

    CLAUSES = collections.OrderedDict([
        ("OPTIONS", test_clause.OPTIONS),
        ("FIELDS", test_clause.FIELDS),
        ("FROM", test_clause.FROM),
        ("WHERE", test_clause.WHERE),
        ("GROUP_BY", test_clause.GROUP_BY),
        ("HAVING", test_clause.HAVING),
        ("ORDER_BY", test_clause.ORDER_BY),
        ("LIMIT", test_clause.LIMIT)
    ])


class INSERT(relations_sql.INSERT):

    CLAUSES = collections.OrderedDict([
        ("OPTIONS", test_clause.OPTIONS),
        ("TABLE", test_expression.TABLE),
        ("FIELDS", test_expression.NAMES),
        ("VALUES", test_clause.VALUES),
        ("SELECT", SELECT)
    ])


class UPDATE(relations_sql.UPDATE):

    CLAUSES = collections.OrderedDict([
        ("OPTIONS", test_clause.OPTIONS),
        ("TABLE", test_expression.TABLE),
        ("SET", test_clause.SET),
        ("WHERE", test_clause.WHERE),
        ("ORDER_BY", test_clause.ORDER_BY),
        ("LIMIT", test_clause.LIMIT)
    ])


class DELETE(relations_sql.DELETE):

    CLAUSES = collections.OrderedDict([
        ("OPTIONS", test_clause.OPTIONS),
        ("TABLE", test_expression.TABLE),
        ("WHERE", test_clause.WHERE),
        ("ORDER_BY", test_clause.ORDER_BY),
        ("LIMIT", test_clause.LIMIT)
    ])

In the case of query classes, the OrderedDict's there also specific the order in which clauses are generated and appended. So it's pretty easy to extend.

Release files for relations-sql 0.6.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for relations-sql 0.6.9
File Size Uploaded
relations_sql-0.6.9.tar.gz 17.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for relations-sql 0.6.9
File Interpreter ABI Platform
relations_sql-0.6.9-py3-none-any.whl Python 3 none any Details

Total release size: 37.6 kB

Release files / relations_sql-0.6.9.tar.gz

Download URL relations_sql-0.6.9.tar.gz
Size 17.2 kB
Tags Source
SHA-256 checksum
How to use checksums
b28b3de415f078feb14065b5ae5f5090a6dd52b121cc8002d055d74b443f3707
BLAKE2b-256 checksum
How to use checksums
e5df3bfdf3660e76a05200e35a6ce72dfc66cbb8ae693ec27acf7cc05a8da72a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.5

Release files / relations_sql-0.6.9-py3-none-any.whl

Download URL relations_sql-0.6.9-py3-none-any.whl
Size 20.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
10d95830be2437e9cd6b8e91337d4e62103f1ea55a15ee976f72aa766dc8611c
BLAKE2b-256 checksum
How to use checksums
e5e69790fefc30614cfa62c28daf52ff9e319324955a37d2d45a4a1e99342286
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.5

Release history Release notifications | RSS feed

This release

0.6.9 This release

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.6.6

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page