GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Blog
  • Docs
  • Log in
  • Register
  • Getting help
  • Installing packages
  • Uploading packages
  • Packaging user guide
  • Infrastructure dashboard
  • Statistics
  • Logos & trademarks
  • Our sponsors
  • Bugs and feedback
  • Contribute on GitHub

This view

  • Original page
  • New address

GeezerVison is showing pypi.org — python-sql

python-sql 1.8.1

Library to write SQL queries

pip install python-sql

python-sql

python-sql is a library to write SQL queries in a pythonic way.

Nutshell

Import:

>>> from sql import *
>>> from sql.aggregate import *
>>> from sql.conditionals import *

Simple selects:

>>> user = Table('user')
>>> select = user.select()
>>> tuple(select)
('SELECT * FROM "user" AS "a"', ())

>>> select = user.select(user.name)
>>> tuple(select)
('SELECT "a"."name" FROM "user" AS "a"', ())

>>> select = user.select(Count(Literal(1)))
>>> tuple(select)
('SELECT COUNT(%s) FROM "user" AS "a"', (1,))

>>> select = user.select(user.name, distinct=True)
>>> tuple(select)
('SELECT DISTINCT "a"."name" FROM "user" AS "a"', ())

>>> select = user.select(user.id, user.name)
>>> tuple(select)
('SELECT "a"."id", "a"."name" FROM "user" AS "a"', ())

Select with where condition:

>>> select.where = user.name == 'foo'
>>> tuple(select)
('SELECT "a"."id", "a"."name" FROM "user" AS "a" WHERE "a"."name" = %s', ('foo',))

>>> select.where = (user.name == 'foo') & (user.active == True)
>>> tuple(select)
('SELECT "a"."id", "a"."name" FROM "user" AS "a" WHERE ("a"."name" = %s) AND ("a"."active" = %s)', ('foo', True))
>>> select.where = user.name == user.login
>>> tuple(select)
('SELECT "a"."id", "a"."name" FROM "user" AS "a" WHERE "a"."name" = "a"."login"', ())

Select with join:

>>> join = user.join(Table('user_group'))
>>> join.condition = join.right.user == user.id
>>> select = join.select(user.name, join.right.group)
>>> tuple(select)
('SELECT "a"."name", "b"."group" FROM "user" AS "a" INNER JOIN "user_group" AS "b" ON "b"."user" = "a"."id"', ())

Select with multiple joins:

>>> join1 = user.join(Table('user'))
>>> join2 = join1.join(Table('user'))
>>> select = join2.select(user.id, join1.right.id, join2.right.id)
>>> tuple(select)
('SELECT "a"."id", "b"."id", "c"."id" FROM "user" AS "a" INNER JOIN "user" AS "b" INNER JOIN "user" AS "c"', ())

Select with group_by:

>>> invoice = Table('invoice')
>>> select = invoice.select(Sum(invoice.amount), invoice.currency,
...         group_by=invoice.currency)
>>> tuple(select)
('SELECT SUM("a"."amount"), "a"."currency" FROM "invoice" AS "a" GROUP BY "a"."currency"', ())

Select with output name:

>>> tuple(user.select(user.name.as_('First Name')))
('SELECT "a"."name" AS "First Name" FROM "user" AS "a"', ())

Select with order_by:

>>> tuple(user.select(order_by=user.date))
('SELECT * FROM "user" AS "a" ORDER BY "a"."date"', ())
>>> tuple(user.select(order_by=Asc(user.date)))
('SELECT * FROM "user" AS "a" ORDER BY "a"."date" ASC', ())
>>> tuple(user.select(order_by=(user.date.asc, user.id.desc)))
('SELECT * FROM "user" AS "a" ORDER BY "a"."date" ASC, "a"."id" DESC', ())

Select with sub-select:

>>> user_group = Table('user_group')
>>> subselect = user_group.select(user_group.user,
...     where=user_group.active == True)
>>> user = Table('user')
>>> tuple(user.select(user.id, where=user.id.in_(subselect)))
('SELECT "a"."id" FROM "user" AS "a" WHERE "a"."id" IN (SELECT "b"."user" FROM "user_group" AS "b" WHERE "b"."active" = %s)', (True,))
>>> tuple(subselect.select(subselect.user))
('SELECT "a"."user" FROM (SELECT "b"."user" FROM "user_group" AS "b" WHERE "b"."active" = %s) AS "a"', (True,))

Select on other schema:

>>> other_table = Table('user', 'myschema')
>>> tuple(other_table.select())
('SELECT * FROM "myschema"."user" AS "a"', ())

Insert query with default values:

>>> tuple(user.insert())
('INSERT INTO "user" DEFAULT VALUES', ())

Insert query with values:

>>> tuple(user.insert(columns=[user.name, user.login],
...         values=[['Foo', 'foo']]))
('INSERT INTO "user" ("name", "login") VALUES (%s, %s)', ('Foo', 'foo'))
>>> tuple(user.insert(columns=[user.name, user.login],
...         values=[['Foo', 'foo'], ['Bar', 'bar']]))
('INSERT INTO "user" ("name", "login") VALUES (%s, %s), (%s, %s)', ('Foo', 'foo', 'Bar', 'bar'))

Insert query with query:

>>> passwd = Table('passwd')
>>> select = passwd.select(passwd.login, passwd.passwd)
>>> tuple(user.insert(values=select))
('INSERT INTO "user" SELECT "a"."login", "a"."passwd" FROM "passwd" AS "a"', ())

Update query with values:

>>> tuple(user.update(columns=[user.active], values=[True]))
('UPDATE "user" AS "a" SET "active" = %s', (True,))
>>> tuple(invoice.update(columns=[invoice.total], values=[invoice.amount + invoice.tax]))
('UPDATE "invoice" AS "a" SET "total" = "a"."amount" + "a"."tax"', ())

Update query with where condition:

>>> tuple(user.update(columns=[user.active], values=[True],
...          where=user.active == False))
('UPDATE "user" AS "a" SET "active" = %s WHERE "a"."active" = %s', (True, False))

Update query with from list:

>>> group = Table('user_group')
>>> tuple(user.update(columns=[user.active], values=[group.active],
...         from_=[group], where=user.id == group.user))
('UPDATE "user" AS "b" SET "active" = "a"."active" FROM "user_group" AS "a" WHERE "b"."id" = "a"."user"', ())

Delete query:

>>> tuple(user.delete())
('DELETE FROM "user"', ())

Delete query with where condition:

>>> tuple(user.delete(where=user.name == 'foo'))
('DELETE FROM "user" WHERE "name" = %s', ('foo',))

Delete query with sub-query:

>>> tuple(user.delete(
...             where=user.id.in_(user_group.select(user_group.user))))
('DELETE FROM "user" WHERE "id" IN (SELECT "a"."user" FROM "user_group" AS "a")', ())

Flavors:

>>> select = user.select()
>>> select.offset = 10
>>> Flavor.set(Flavor())
>>> tuple(select)
('SELECT * FROM "user" AS "a" OFFSET %s', (10,))
>>> Flavor.set(Flavor(max_limit=18446744073709551615))
>>> tuple(select)
('SELECT * FROM "user" AS "a" LIMIT 18446744073709551615 OFFSET %s', (10,))
>>> Flavor.set(Flavor(max_limit=-1))
>>> tuple(select)
('SELECT * FROM "user" AS "a" LIMIT -1 OFFSET %s', (10,))

Limit style:

>>> select = user.select(limit=10, offset=20)
>>> Flavor.set(Flavor(limitstyle='limit'))
>>> tuple(select)
('SELECT * FROM "user" AS "a" LIMIT %s OFFSET %s', (10, 20))
>>> Flavor.set(Flavor(limitstyle='fetch'))
>>> tuple(select)
('SELECT * FROM "user" AS "a" OFFSET (%s) ROWS FETCH FIRST (%s) ROWS ONLY', (20, 10))
>>> Flavor.set(Flavor(limitstyle='rownum'))
>>> tuple(select)
('SELECT "a".* FROM (SELECT "b".*, ROWNUM AS "rnum" FROM (SELECT * FROM "user" AS "c") AS "b" WHERE ROWNUM <= %s) AS "a" WHERE "rnum" > %s', (30, 20))

qmark style:

>>> Flavor.set(Flavor(paramstyle='qmark'))
>>> select = user.select()
>>> select.where = user.name == 'foo'
>>> tuple(select)
('SELECT * FROM "user" AS "a" WHERE "a"."name" = ?', ('foo',))

numeric style:

>>> Flavor.set(Flavor(paramstyle='format'))
>>> select = user.select()
>>> select.where = user.name == 'foo'
>>> format2numeric(*select)
('SELECT * FROM "user" AS "a" WHERE "a"."name" = :0', ('foo',))

Project links

  • changelog
  • forum
  • homepage
  • issues
  • repository

Key dates

PyPI data
Data sourced directly from PyPI's database.
  • Released: Apr 3, 2026
Latest release

Owner

PyPI data
Data sourced directly from PyPI's database.
  • Tryton

Credits

Author: B2CK SRL

Maintainer: Tryton

License expression

BSD-3-Clause
View SPDX License List

Requires

Python >=3.9

Tags

SQL database query

Classifiers

  • Development Status
    • 5 - Production/Stable
  • Intended Audience
    • Developers
  • Topic
    • Database
    • Software Development :: Libraries :: Python Modules

Metadata

Project links

  • changelog
  • forum
  • homepage
  • issues
  • repository

Key dates

PyPI data
Data sourced directly from PyPI's database.
  • Released: Apr 3, 2026
Latest release

Owner

PyPI data
Data sourced directly from PyPI's database.
  • Tryton

Credits

Author: B2CK SRL

Maintainer: Tryton

License expression

BSD-3-Clause
View SPDX License List

Requires

Python >=3.9

Tags

SQL database query

Classifiers

  • Development Status
    • 5 - Production/Stable
  • Intended Audience
    • Developers
  • Topic
    • Database
    • Software Development :: Libraries :: Python Modules

Release files for python-sql 1.8.1

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

Source distribution (sdist)

Source distribution for python-sql 1.8.1
File Size Uploaded Provenance Actions
python_sql-1.8.1.tar.gz 34.4 kB Apr 3, 2026 Without provenance Details for python_sql-1.8.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for python-sql 1.8.1
File Interpreter ABI Platform Actions Reset
python_sql-1.8.1-py3-none-any.whl 50.8 kB Apr 3, 2026 Without provenance Python 3 none any Details for python_sql-1.8.1-py3-none-any.whl

Total release size: 85.2 kB

Release files / python_sql-1.8.1.tar.gz

Download URL python_sql-1.8.1.tar.gz
Size 34.4 kB
Tags Source
SHA-256 checksum
How to use checksums
9cdf51e802276fe5bc981f5b222dbc612b952c0e3f91c95ede7efdffe75770b0
BLAKE2b-256 checksum
How to use checksums
f18c29e12447ec5a36db471ad6e1ab0bfe2d326e596277c4b82c481f683086ec
Upload date Apr 3, 2026
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.11

Release files / python_sql-1.8.1-py3-none-any.whl

Download URL python_sql-1.8.1-py3-none-any.whl
Size 50.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5d2091a2c9cb7684930e68eeccc8251c51dc95332126c6173d07c85c2587e8ff
BLAKE2b-256 checksum
How to use checksums
77ac3603bbdde340f7354c975431c94b70ef3e99966c5b170fa121f8e64d269e
Upload date Apr 3, 2026
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.11

Security for python-sql 1.8.1

Report project as malware

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.8.1 This release

Apr 3, 2026 2 release files No provenance

1.8.0

Mar 21, 2026 2 release files No provenance

1.7.0

Nov 24, 2025 2 release files No provenance

1.6.0

May 2, 2025 2 release files No provenance

1.5.2

Sep 30, 2024 2 release files No provenance

1.5.1

May 28, 2024 2 release files No provenance

1.5.0

May 13, 2024 2 release files No provenance

1.4.3

Dec 30, 2023 2 release files No provenance

1.4.2

Jun 25, 2023 2 release files No provenance

1.4.1

Jun 16, 2023 2 release files No provenance

1.4.0

May 2, 2022 2 release files No provenance

1.3.0

Sep 14, 2021 2 release files No provenance

1.2.2

May 16, 2021 3 release files No provenance

1.2.1

Oct 8, 2020 3 release files No provenance

1.2.0

Oct 5, 2020 2 release files No provenance

1.1.0

Jan 25, 2020 3 release files No provenance

1.0.0

Sep 30, 2018 3 release files No provenance

0.9

Apr 24, 2017 3 release files No provenance

0.8

Sep 19, 2015 1 release file No provenance

0.7

May 19, 2015 1 release file No provenance

0.6

Feb 5, 2015 1 release file No provenance

0.5

Jan 29, 2015 1 release file No provenance

0.4

Aug 3, 2014 1 release file No provenance

0.3

Jan 31, 2014 1 release file No provenance

0.2

Sep 18, 2013 1 release file No provenance

0.1

Aug 28, 2013 1 release file No provenance

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.