Package: asyncsql
AsyncSQLAsyncSQL aims to provide simple and efficient way to perform PostgreSQL
requests with aiohttp.InstallAs python library AsyncSQL may be installed as follows:(venv)$pipinstallasyncsqlSettingsTo connect to PostgreSQL common env vars should use.For example the following values can be used when develop:$exportPGHOST=172.19.0.2# depends on which IP postgres container is using$exportPGDATABASE=asyncsql
$exportPGUSER=postgres
$exportPGPASSWORD=xxxBy default listing data is paginated. The page size can be specify as follows:$exportASYNCSQL_PER_PAGE=25# default: 50Folder containing .sql files can be specify as follows:$exportASYNCSQL_SQL_DIR=./tests/data# default: ./sql_filesMigrateTo ease db setup a simplemigratecommand is provided by AsyncSQL.For example, we can load tests data as follows:(venv)$python-masyncsql.migrate-d./tests/datajobs# file-2 file-3jobs...okNo magic bullet here, files order matters and idempotency too.UsageLet's perform some queries on ourjobstest table.First we need to define aModelobject to work with in our python code:fromdatetimeimportdatetimefromtypingimportOptionalfromuuidimportUUIDfromasyncsql.modelsimportModelclassJob(Model):id:Optional[UUID]=Noneenabled:bool=Falsefunc:strname:strcreated_at:Optional[datetime]=Noneupdated_at:Optional[datetime]=NoneThen we need aQueriesinstance:fromasyncsql.queriesimportQueriesjobs_queries=Queries("jobs",model_cls=Job,order_fields=("name",))Let's connect as follows:importasynciofromasyncsql.backendsimportsql_backendconn=awaitsql_backend.connAs the db is empty simpleselectshould return an empty list andhas_nextflag toFalse:awaitjobs_queries.select(conn)# ([], False)Let's insert some data:forxinrange(10):awaitjobs_queries.insert(conn,Job(func="ping",name=f"ping-{x}"))We should now have the following data:[j.nameforjin(awaitjobs_queries.select(conn))[0]]# ['ping-0',#  'ping-1',#  'ping-2',#  'ping-3',#  'ping-4',#  'ping-5',#  'ping-6',#  'ping-7',#  'ping-8',#  'ping-9']We can limit the result changing theper_pagevalue as follows:jobs_queries.per_page=3jobs,has_next=awaitjobs_queries.select(conn)[j.nameforjinjobs],has_next# (['ping-0', 'ping-1', 'ping-2'], True)As we would do in an API, we can get the next page with aCursorobject
as follows:fromasyncsql.cursorimportCursorCursor(fields=("name",),obj=jobs[-1])# gASV6wAAAAAAAAAojANhc2OUfZQojAJpZJSMJDRlNTM1YTQ4LWJmMjgtMTFlYi05ZDc3LTAyNDJhYzEzMDAwMpSMB2VuYWJsZWSUiYwEZnVuY5SMBHBpbmeUjARuYW1llIwGcGluZy0ylIwKY3JlYXRlZF9hdJSMCGRhdGV0aW1llIwIZGF0ZXRpbWWUk5RDCgflBRsUDycNJDGUaAqMCHRpbWV6b25llJOUaAqMCXRpbWVkZWx0YZSTlEsASwBLAIeUUpSFlFKUhpRSlIwKdXBkYXRlZF9hdJRoDEMKB+UFGxQPJw0kMZRoFYaUUpR1KX2UdJQuwhere,values,_=jobs_queries.get_where_from_cursor(_)where,values# ('name >= $1 AND id != $2', ['ping-2', '4e535a48-bf28-11eb-9d77-0242ac130002'])jobs,has_next=awaitjobs_queries.select(conn,values=values,where=where)[j.nameforjinjobs],has_next# (['ping-3', 'ping-4', 'ping-5'], True)Jobobject can be use for update too:job=(awaitjobs_queries.select(conn,values=("ping-9",),where="name = $1"))[0][0]job.id,job.name# ('4e5692d0-bf28-11eb-9d77-0242ac130002', 'ping-9')job.name="ping-x"new_job=awaitjobs_queries.update(conn,job)new_job.name# ping-xLet's clean this demo:jobs_queries.per_page=10forjin(awaitjobs_queries.select(conn))[0]:awaitjobs_queries.delete_by_id(conn,j.id)Ideasmake smaller cursor: serializing the whole object may be an overheadwork with templated .sql files instead of hard codedsqlstrings inQueriesContributingContribution is welcome. It may be simple but tested as it started.LicenseMIT