Skip to main content

never forget:

python setup.py sdist bdist_wheel && python -m twine upload dist/* --skip-existing # UPLOAD TO PYPI

python-gstorm

Graphql Simple Tiny Object Relational Mapping - Graphql ORM for python

Current features:

QUERY

Aliases

There are several aliases for most Query-building functions, which make queries more concise:

  • query
    • q = query, example: Type.q() # vs Type.query()
    • qm = query, example: Type.qm() # vs Type.query()
  • query_one
    • q1 = query_one, example: Type.q1() # vs Type.query_one()
    • qs = query_one, example: Type.qs() # vs Type.query_one()
  • filter
    • fil = filter, example: Type.q().fil(...) # vs Type.query().filter(...)
    • after
      • long: Type.query().filter(after={'attribute': x, 'date': y})
      • short: Type.q().after(attr=x, date=y)
    • before
      • long: Type.query().filter(before={'attribute': x, 'date': y})
      • short: Type.q().before(attr=x, date=y)
    • isNull
      • long: Type.query().filter(nullAttribute={'attribute': x, 'isNull': y})
      • short: Type.q().isNull(attr=x, value=True)
      • shorter: Type.q().isNull(attr=x) (Defaults to True)
  • findBy
    • fb = findBy, example: Type.q(). # vs Type.query().
    • find = findBy, example: Type.q(). # vs Type.query().
  • orderBy
    • ob = orderBy, example: Type.q(). # vs Type.query().
    • order = orderBy, example: Type.q(). # vs Type.query().
  • limit
    • lim = limit, example: Type.q(). # vs Type.query().
  • offset
    • off = offset, example: Type.q(). # vs Type.query().
  • children
    • child = children, example: Type.q(). # vs Type.query().
    • ch = children, example: Type.q(). # vs Type.query().
  • get
    • run = get

Query all

from tests.models import Tank
all_tanks = Tank.query().get() # returns -> List[Tank]
print(all_tanks) # [Tank(id=1,capacity=10),Tank(id=2,capacity=20),...]

Query some

You can concatenate storm methods to manipulate the data and how you want to receive it, this methods may receive parameters in several ways:

  • filter(kwargs):
    • .filter(name='L1')
    • .filter({'name': 'L1'})
    • .filter(name='L1').filter(capacity=1250)
    • .filter(name='L1', capacity=1250)
    • .filter({'name': 'L1', 'capacity': 1250})
  • orderBy(kwarg):
    • Accepted keys = [asc, desc]
    • Accepted values = GraphQLType ModelAttr enums.
    • .orderBy(asc=TypeAttrs.ID)
    • .orderBy(desc=TypeAttrs.INSERTED_AT)
  • limit(count)
    • .limit(1)
from tests.models import Tank
all_tanks = (
  Tank.query()
  .filter(capacity=1250)
).get() # returns -> List[Tank]
print(all_tanks) # [Tank(id=1,capacity=10),Tank(id=3,capacity=10),...]

Query one

from tests.models import Tank
my_tank = Tank.query_one().findBy(id=3).get() # returns -> Tank
print(my_tank) # Tank(id='3', name='R342', type='Reposo', capacity=0, room=None, inventories=[])

Filters

per field value (exact match, regex accepted)

from tests.models import Tank
gov_tanks = Tank.query().filter(type='^Gob').get()
rest_tanks = Tank.query().filter(type='^Rep').get()
print(len(gov_tanks))
print(len(rest_tanks))

Null attribute

from tests.models import Tank
ok_tanks = (
  Tank.query().filter(nullAttribute= { 'attribute': 'CAPACITY', 'isNull': False })
).get()
print(ok_tanks)

# short-hand version
from tests.models import Tank
ok_tanks = Tank.q().isNull(attr='CAPACITY', value=False).get()
print(ok_tanks)

# using null default value:
from tests.models import Tank
bad_tanks = Tank.q().isNull(attr='CAPACITY').get() # value param defaults to True
print(bad_tanks)

Comparison dates (after, before)

from tests.models import BbtInventory
from datetime import datetime as dt, timedelta as td
from gstorm.helpers.date_helpers import get_iso8601_str
today = get_iso8601_str(dt.now() - td(days=1))
yesterday = get_iso8601_str(dt.now() - td(days=2))
today_inventories = (
  BbtInventory.query()
    .filter(after={
      'attribute': 'INSERTED_AT',
      'date': "2020-02-27T23:01:44Z" # or: 'date': dt.now() - td(days=1)
    })
).get()
print(today_inventories)

# Short-hand version
today_inventories = (
  BbtInventory.query()
    .after(attr='INSERTED_AT', date="2020-02-27T23:01:44Z") # or: 'date': dt.now() - td(days=1)
).get()
print(today_inventories)

# Short-hand version
yesterday_inventories = (
  BbtInventory.query()
    .after(attr='INSERTED_AT', date=yesterday)
    .before(attr='INSERTED_AT', date=today)
).get()
print(yesterday_inventories)

Ordering

Asc, Desc, per field

from tests.models import BbtInventory
latest_inventories = BbtInventory.query().orderBy(desc=BbtInventoryAttrs.ID).limit(5).get()
print(latest_inventories)
smallest_inventories = BbtInventory.query().orderBy(asc=BbtInventoryAttrs.VOLUME).limit(5).get()
print(smallest_inventories)

Limit

from tests.models import BottlingLine
first_10_lines = BottlingLine.query().limit(10).get()
print(first_10_lines)

Nested Queries

from tests.models import BottlingOrder
# We want to include the sub-attributes:
guid = 'abc123'
orders = BottlingOrder.query()._with({
  'line': Line.query(),
  'plans': BottlingPlan.query().orderBy(asc=BottlingPlanAttrs.ID),
  'brightBeer': BrightBeer.query().filter(groupGuid=guid))
}).
print(orders[0])
# >> BottlingOrder(id=1, name='123', line=Line(name='LINEA001'), ...)

Pagination (API NOT FINAL)

iterable

from tests.models import Datum
order = {'desc': 'ID'}
for datum_page in Datum.limit(100).offset(0).orderBy(asc=DatumAttrs.ORDER).paginate():
  for datum in datum_page:
    print(datum) # type: Datum(id=x,value=y)

Comparison numerical (>, >=, <, <=...)

NOT WORKING IN VALIOT-APP

MUTATION

Create

from tests.models import Tank
tank = Tank.load(csv='tanks.csv').limit(1).get() # load from any source
response = storm.create(tank) # GraphqlType object

Update

from tests.models import Tank
[gov_tank] = Tank.query().filter(name='L').limit(1).get()
# process data...
# ...
response = storm.update(gov_tank).apply() # GraphqlType object

Upsert

from tests.models import Tank
[gov_tank] = Tank.load(csv='tanks.csv').limit(1).get() # load from any source
response = storm.upsert(gov_tank).apply() # GraphqlType object
if not response.successful:
  print(response.messages)
# everything ok, do other stuff...
print(gov_tank) # has updated data (New ID, etc)

Single mutation

See above examples

Multiple mutation

Sequential

from tests.models import Tank
gov_tanks = Tank.load(csv='tanks.csv').get() # load from any source
# ! OPTION 1: one by one
for tank in gov_tanks:
  response = storm.upsert(tank).apply() # GraphqlType object
  print(tank) # has updated data (New ID, etc)
# ! OPTION 2: All handled by storm:
response = storm.upsert(gov_tanks).apply()
# response type -> List[GraphqlMutationResponse]

Batch (Multiple mutations in single Mutation tag)

from tests.models import Tank
from storm import UploadMode as mode
gov_tanks = Tank.load(csv='tanks.csv') # load from any source
response = storm.upsert(gov_tanks).mode(mode.BATCH).apply()
# default:
# response = storm.upsert(gov_tanks, mode=mode.SEQUENTIAL)

Nested mutation

API WIP:

from tests.models import BbtProgram, BbtPlan
from storm import UploadMode as mode
# algorithm runs...
program = BbtProgram() # New with defaults
for plan in algorithm_plans:
  program.plans.append(BbtPlan(**plan))
# OPTION 1:
response = storm.create(program)
  .nested({
    'plans': Plan.create()
  }).apply()
# OPTION 2:
attrs = ['plans']
response = storm.create(program, nested=attrs)

Parallel/Batch (Multiple mutations multi-threaded, each mutation may be batched)

NOT PRIORITY

SUBSCRIPTION

NOT PRIORITY

COMPARISON

# # ! old way [No additional libraries]:
# import requests
# import json
# @dataclass
# class Line():
#   id: str
#   name: str
#   speed: float

# LINE = '''
#   query getLine($name: String!){
#     line(findBy:{ name: $name }){
#       id
#       name
#       speed
#     }
#   }
# '''
# url = 'https://test.valiot.app/'
# content = {
#   'query': LINE,
#   'variables': {'name': 'LINEA001'}
# }
# response = requests.post(url, json=content)
# line_data = json.loads(str(response.content))
# line = Line(**line_data)
# line.name # * >> LINEA001
# # ! current way [pygqlc]:
# gql = GraphQLClient()
# @dataclass
# class Line():
#   id: str
#   name: str
#   speed: float

# LINE = '''
#   query getLine($name: String!){
#     line(findBy:{ name: $name }){
#       id
#       name
#       speed
#     }
#   }
# '''
# line_data, _ = gql.query_one(LINE, {'name': 'LINEA001'})
# line = Line(**line_data)
# line.name # * >> LINEA001

# # * New way (TBD):
# gql = GraphQLClient()
# orm = GStorm(client=gql, schema=SCHEMA_PATH)
# Line = orm.getType('Line')
# line = Line.find_one({'name': 'LINEA001'})
# line.name # * >> LINEA001

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gstorm-0.12.4.tar.gz (33.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gstorm-0.12.4-py3-none-any.whl (36.2 kB view details)

Uploaded Python 3

File details

Details for the file gstorm-0.12.4.tar.gz.

File metadata

  • Download URL: gstorm-0.12.4.tar.gz
  • Upload date:
  • Size: 33.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.7

File hashes

Hashes for gstorm-0.12.4.tar.gz
Algorithm Hash digest
SHA256 4c5541ded405706363a6717f1187b0af5061997de525d1d955700eeea100ce41
MD5 d3bfa006e1f487bc33f8bb5618f19e12
BLAKE2b-256 89c01792c7ff4eed9990dac39449a4f123b4546485c1d394bc95a17eb5130a06

See more details on using hashes here.

File details

Details for the file gstorm-0.12.4-py3-none-any.whl.

File metadata

  • Download URL: gstorm-0.12.4-py3-none-any.whl
  • Upload date:
  • Size: 36.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.7

File hashes

Hashes for gstorm-0.12.4-py3-none-any.whl
Algorithm Hash digest
SHA256 f83c59c8660e1e32d3982f2393cd5eee51f854f9a31234af38680c8d5dc1e166
MD5 18bcd7fcdf706d5aee36b5323ac3cd4e
BLAKE2b-256 d5af2e952c1e761dee7b1bca6584f98bcd0f04b8c8a5cb6c06ef7839fd35a69c

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.12.4 This release

2 files

0.12.3

2 files

0.12.2

2 files

0.12.1

2 files

0.12.0

2 files

0.11.0

2 files

0.10.3

2 files

0.10.2

2 files

0.10.1

2 files

0.10.0

3 files

0.9.1

1 file

0.9.0

2 files

0.8.1

2 files

0.8.0

2 files

0.7.1

2 files

0.7.0

2 files

0.6.4

2 files

0.6.3

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.0

2 files

0.4.13

2 files

0.4.12

2 files

0.4.11

2 files

0.4.10

2 files

0.4.9

2 files

0.4.8

2 files

0.4.7

2 files

0.4.6

2 files

0.4.5

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.5

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page