Codebase list anosql / 040f7c8
Import upstream version 1.0.2 Debian Janitor 2 years ago
16 changed file(s) with 108 addition(s) and 58 deletion(s). Raw diff Collapse all Expand all
0 dist: xenial
01 language: python
12 python:
23 - "2.7"
34 - "3.5"
4 services:
5 - postgresql
6 addons:
7 postgresql: "10"
8 apt:
9 packages:
10 - postgresql-10
11 - postgresql-client-10
12 - postgresql-server-dev-10
13 install: "pip install tox"
5 - "3.7"
6 matrix:
7 include:
8 - python: "3.7"
9 env: TOXENV=flake8
10 - python: "3.7"
11 env: TOXENV=docs
12 - python: "3.7"
13 env: TOXENV=check-manifest
14 before_install:
15 # don't install postgresql for flake8 and docs environments
16 - if test -z "$TOXENV"; then sudo apt-get -y install --no-install-recommends postgresql-11 postgresql-client-11 postgresql-server-dev-11; fi
17 install: "pip install tox-travis"
1418 script: tox
0 include README.md
0 include README.rst
1 include CHANGELOG
2 include LICENSE
3 include tox.ini
4 include test_requirements.txt
5 recursive-include docs *.rst Makefile conf.py make.bat
6 recursive-include tests *.csv *.sql
22
33 .. image:: https://badge.fury.io/py/anosql.svg
44 :target: https://badge.fury.io/py/anosql
5 :alt: pypi package version
56
67 .. image:: http://readthedocs.org/projects/anosql/badge/?version=latest
78 :target: http://anosql.readthedocs.io/en/latest/?badge=latest
910
1011 .. image:: https://travis-ci.org/honza/anosql.svg?branch=master
1112 :target: https://travis-ci.org/honza/anosql
13 :alt: Travid build status
1214
1315 A Python library for using SQL
1416
1517 Inspired by the excellent `Yesql`_ library by Kris Jenkins. In my mother
1618 tongue, *ano* means *yes*.
1719
18 If you are on python3.6+ or need ``anosql`` to work with ``asyncio`` based database drivers.
19 See the related project `aiosql <https://github.com/nackjicholson/aiosql>`_.
20 If you are on python3.6+ or need ``anosql`` to work with ``asyncio``-based database drivers, see the related project, `aiosql <https://github.com/nackjicholson/aiosql>`_.
21
22 Complete documentation is available at `Read The Docs <https://anosql.readthedocs.io/en/latest/>`_.
2023
2124 Installation
2225 ------------
3942 -- Get all the greetings in the database
4043 SELECT * FROM greetings;
4144
42 -- name: $select-users
45 -- name: select-users
4346 -- Get all the users from the database,
4447 -- and return it as a dict
4548 SELECT * FROM USERS;
5861
5962 # Or, Sqlite3...
6063 conn = sqlite3.connect('cool.db')
61 queries = anosql.from_path('queries.sql', 'sqlite3)
64 queries = anosql.from_path('queries.sql', 'sqlite3')
6265
6366 queries.get_all_greetings(conn)
6467 # => [(1, 'Hi')]
8184
8285 .. code-block:: sql
8386
84 -- name: get-greetings-for-language-and-length
85 -- Get all the greetings in the database
87 -- name: get-greetings-for-language
88 -- Get all the greetings in the database for given language
8689 SELECT *
8790 FROM greetings
8891 WHERE lang = %s;
9295 .. code-block:: python
9396
9497 visitor_language = "en"
95 queries.get_all_greetings(conn, visitor_language)
98 queries.get_greetings_for_language(conn, visitor_language)
9699
97100
98101
105108 .. code-block:: sql
106109
107110 -- name: get-greetings-for-language-and-length
108 -- Get all the greetings in the database
111 -- Get all the greetings in the database for given language and length
109112 SELECT *
110113 FROM greetings
111114 WHERE lang = :lang
121124
122125 visitor_language = "en"
123126
124 greetings_for_texting = queries.get_all_greetings(
127 greetings_for_texting = queries.get_greetings_for_language_and_length(
125128 conn, lang=visitor_language, length_limit=140)
126129
127130 Update/Insert/Delete
145148 Adding custom query loaders.
146149 ****************************
147150
148 Out of the box ``anosql`` supports SQLite and PostgreSQL via the stdlib ``sqlite3`` database driver
149 and ``psycopg2``. If you would like to extend ``anosql`` to communicate with another type of databases
150 you may create a driver adapeter class and register it with ``anosql.register_driver_adapter()``.
151 Out of the box, ``anosql`` supports SQLite and PostgreSQL via the stdlib ``sqlite3`` database driver
152 and ``psycopg2``. If you would like to extend ``anosql`` to communicate with other types of databases,
153 you may create a driver adapter class and register it with ``anosql.core.register_driver_adapter()``.
151154
152155 Driver adapters are duck-typed classes which adhere to the below interface. Looking at ``anosql/adapters`` package
153156 is a good place to get started by looking at how the ``psycopg2`` and ``sqlite3`` adapters work.
155158 To register a new loader::
156159
157160 import anosql
161 import anosql.core
158162
159163 class MyDbAdapter():
160164 def process_sql(self, name, op_type, sql):
180184 pass
181185
182186
183 anosql.register_driver_adapter("mydb", MyDbAdapter)
187 anosql.core.register_driver_adapter("mydb", MyDbAdapter)
184188
185189 # To use make a connection to your db, and pass "mydb" as the db_type:
186190 import mydbdriver
191195
192196 conn.close()
193197
194 If your adapter constructor takes arguments you can register a function which can build
198 If your adapter constructor takes arguments, you can register a function which can build
195199 your adapter instance::
196200
197201 def adapter_factory():
11 from anosql.exceptions import SQLLoadException, SQLParseException
22
33 __all__ = ["from_path", "from_str", "SQLOperationType", "SQLLoadException", "SQLParseException"]
4
4040 cur.execute(sql, parameters)
4141
4242 @staticmethod
43 def insert_update_delete_many(conn, _query_name, sql, parmeters):
43 def insert_update_delete_many(conn, _query_name, sql, parameters):
4444 with conn.cursor() as cur:
45 cur.executemany(sql, parmeters)
45 cur.executemany(sql, parameters)
4646
4747 @staticmethod
4848 def insert_returning(conn, _query_name, sql, parameters):
2222 var_pattern = re.compile(
2323 r'(?P<dblquote>"[^"]+")|'
2424 r"(?P<quote>\'[^\']+\')|"
25 r"(?P<lead>[^:]):(?P<var_name>[\w-]+)(?P<trail>[^:])"
25 r"(?P<lead>[^:]):(?P<var_name>[\w-]+)(?P<trail>[^:]?)"
2626 )
2727 """
2828 Pattern: Identifies variable definitions in SQL code.
1818 # import os
1919 # import sys
2020 # sys.path.insert(0, os.path.abspath('.'))
21 import pkg_resources
2122
2223 # -- General configuration ------------------------------------------------
2324
5657 # built documents.
5758 #
5859 # The short X.Y version.
59 version = u'1.0.0'
60 version = pkg_resources.get_distribution('anosql').version
6061 # The full version, including alpha/beta/rc tags.
61 release = u'1.0.0'
62 release = version
6263
6364 # The language for content autogenerated by Sphinx. Refer to documentation
6465 # for a list of supported languages.
152153 # Add any paths that contain custom static files (such as style sheets) here,
153154 # relative to this directory. They are copied after the builtin static files,
154155 # so a file named "default.css" will overwrite the builtin "default.css".
155 html_static_path = ['_static']
156 html_static_path = []
156157
157158 # Add any extra paths that contain custom files (such as robots.txt or
158159 # .htaccess) here, relative to this directory. These files are copied
55 ======================
66
77 Name definitions are how ``anosql`` determines how to name the SQL code blocks which are loaded.
8 A query name definition is a normal SQL comment starting with "-- name:" and is followed by the
9 name of the query. You can use ``-`` or ``_`` in your query names, but the methods in python
10 will always be valid python names using underscores.
8 A query name definition is a normal SQL comment starting with "\-\- name:" and is followed by the
9 name of the query. You can use ``-`` or ``_`` in your query names, but the methods in Python
10 will always be valid Python names using underscores.
1111
1212 .. code-block:: sql
1313
1717 The above example when loaded by ``anosql.from_path`` will return an object with a
1818 ``.get_all_blogs(conn)`` method.
1919
20 Your SQL comments will be added to your methods as python documentation, and accessible by calling
20 Your SQL comments will be added to your methods as Python docstrings, and accessible by calling
2121 ``help()`` on them.
2222
2323 .. code-block:: sql
3232 queries = anosql.from_path("blogs.sql", "sqlite3")
3333 help(anosql.get_all_blogs)
3434
35 output
35 returns
3636
3737 .. code-block:: text
3838
5151 characters trailing it. This lack of operator is actually the most basic operator which performs
5252 SQL ``select`` statements and returns a list of rows. When writing an application you will often
5353 need to perform other operations besides selects, like inserts, deletes, and bulk opearations. The
54 operators detailed in this section let you declare in your SQL, how your code should be executed
54 operators detailed in this section let you declare in your SQL how your code should be executed
5555 by the database driver.
5656
5757 Insert/Update/Delete with ``!``
141141 :published
142142 )
143143
144 Applying this to a list of blogs in python::
144 Applying this to a list of blogs in Python::
145145
146146 queries = anosql.from_path("blogs.sql", "psycopg2")
147147 blogs = [
154154 Execute SQL script statements with ``#``
155155 ---------------------------------------------
156156
157 Executes some sql statements as a script. These methods don't do variable substitution, or return
158 any rows. An example usecase is using data definition statements like create table in order to
157 Executes some SQL statements as a script. These methods don't do variable substitution, or return
158 any rows. An example use case is using data definition statements like `create` table in order to
159159 setup your database.
160160
161161 .. code-block:: sql
33 Extending anosql
44 ################
55
6 .. _driver-adapters:
7
68 Driver Adapters
79 ---------------
810
9 Database driver adapters in ``anosql`` are a duck-typed class which follow the below interface.::
11 Database driver adapters in ``anosql`` are duck-typed classes which follow the below interface.::
1012
1113 class MyDbAdapter():
1214 def process_sql(self, name, op_type, sql):
3234 pass
3335
3436
35 anosql.register_driver_adapter("mydb", MyDbAdapter)
37 anosql.core.register_driver_adapter("mydb", MyDbAdapter)
3638
3739 If your adapter constructor takes arguments you can register a function which can build
3840 your adapter instance::
4042 def adapter_factory():
4143 return MyDbAdapter("foo", 42)
4244
43 anosql.register_driver_adapter("mydb", adapter_factory)
45 anosql.core.register_driver_adapter("mydb", adapter_factory)
4446
4547 Looking at the source of the builtin
4648 `adapters/ <https://github.com/honza/anosql/tree/master/anosql/adapters>`_ is a great place
2323 from worlds
2424 where world_name = :world_name;
2525
26 By specifying ``db_driver="sqlite3"`` we can use the python stdlib ``sqlite3`` driver to execute these sql queries and
26 By specifying ``db_driver="sqlite3"`` we can use the Python stdlib ``sqlite3`` driver to execute these SQL queries and
2727 get the results. We're also using the ``sqlite3.Row`` type for our records to make it easy to access our data via
2828 their column names rather than as tuple indices.
2929
77
88 .. image:: https://badge.fury.io/py/anosql.svg
99 :target: https://badge.fury.io/py/anosql
10 :alt: pypi package version
1011
1112 .. image:: http://readthedocs.org/projects/anosql/badge/?version=latest
1213 :target: http://anosql.readthedocs.io/en/latest/?badge=latest
14 :alt: Documentation status
1315
1416 .. image:: https://travis-ci.org/honza/anosql.svg?branch=master
1517 :target: https://travis-ci.org/honza/anosql
18 :alt: Travis build status
1619
1720 A Python library for using SQL
1821
1922 Inspired by the excellent `Yesql`_ library by Kris Jenkins. In my mother
2023 tongue, *ano* means *yes*.
2124
22 If you are on python3.6+ or need ``anosql`` to work with ``asyncio`` based database drivers.
23 See the related project `aiosql <https://github.com/nackjicholson/aiosql>`_.
25 If you are on python3.6+ or need ``anosql`` to work with ``asyncio`` based database drivers, see the related project `aiosql <https://github.com/nackjicholson/aiosql>`_.
2426
2527 Installation
2628 ------------
5759
5860 # Or, Sqlite3...
5961 conn = sqlite3.connect('cool.db')
60 queries = anosql.from_path('queries.sql', 'sqlite3)
62 queries = anosql.from_path('queries.sql', 'sqlite3')
6163
6264 queries.get_all_greetings(conn)
6365 # => [(1, 'Hi')]
7577 Parameters
7678 **********
7779
78 Often, you want to change parts of the query dynamically, particularly values in the WHERE clause.
80 Often, you want to change parts of the query dynamically, particularly values in the ``WHERE`` clause.
7981 You can use parameters to do this:
8082
8183 .. code-block:: sql
8284
83 -- name: get-greetings-for-language-and-length
84 -- Get all the greetings in the database
85 -- name: get-greetings-for-language
86 -- Get all the greetings in the database for a given language
8587 SELECT *
8688 FROM greetings
8789 WHERE lang = %s;
9193 .. code-block:: python
9294
9395 visitor_language = "en"
94 queries.get_all_greetings(conn, visitor_language)
96 queries.get_all_greetings_for_language(conn, visitor_language)
9597
9698
9799
102104
103105 .. code-block:: sql
104106
105 -- name: get-greetings-for-language-and-length
106 -- Get all the greetings in the database
107 -- name: get-greetings-for-language
108 -- Get all the greetings in the database for given language and length
107109 SELECT *
108110 FROM greetings
109111 WHERE lang = :lang
0 [bdist_wheel]
1 universal = 1
44
55 setup(
66 name='anosql',
7 version='1.0.1',
7 version='1.0.2',
88 url='https://github.com/honza/anosql',
99 install_requires=[],
1010 description='Easy SQL in Python',
1919 firstname integer not null,
2020 lastname text not null
2121 );
22
22
2323 create table blogs (
2424 blogid integer not null primary key,
2525 userid integer not null,
192192 q.insert_some_value(postgresql)
193193
194194 assert q.get_all_values(postgresql, a=1) == [(1, 2, 3)]
195
196
197 def test_without_trailing_semi_colon_pg():
198 """Make sure keywords ending queries are recognized even without
199 semi-colons.
200 """
201 _queries = ("-- name: get-by-a\n"
202 "SELECT a, b, c FROM foo WHERE a = :a\n")
203 q = anosql.from_str(_queries, "psycopg2")
204 assert q.get_by_a.sql == "SELECT a, b, c FROM foo WHERE a = %(a)s"
00 [tox]
1 envlist = py27, py35
1 envlist = py27, py35, py37, flake8, docs, check-manifest
22 skip_missing_interpreters = True
33
44 [testenv]
55 deps = -rtest_requirements.txt
6 commands = py.test tests
6 commands = {envpython} -m pytest {posargs:tests}
7
8 [testenv:flake8]
9 skip_install = true
10 deps = flake8
11 commands = {envpython} -m flake8 {posargs}
12
13 [flake8]
14 max-line-length=100
15
16 [testenv:docs]
17 deps =
18 sphinx
19 alabaster
20 commands = {envpython} -m sphinx.cmd.build -W -b html docs docs/_build/html
21
22 [testenv:check-manifest]
23 skip_install = true
24 deps =
25 check-manifest
26 commands = {envpython} -m check_manifest