SlideShare a Scribd company logo
ORM vs GraphQL
Oleksandr Tarasenko
EVO.company / prom.ua
Agenda
● Raw SQL in python
● Python ORM libs
● async/await and ORM solutions
● GraphQL implementation
2
WHY?
3
4
5
6
GraphQL
Raw SQL in python
import psycopg2
class pg_conn:
def __enter__(self):
self.conn = psycopg2.connect(
dbname='fwdays', user='highload'
)
return self.conn
def __exit__(self, exc_type, exc_val, exc_tb):
if hasattr(self, 'conn'):
self.conn.close()
7
with pg_conn() as db:
cur = db.cursor()
query = "insert into product('name') values('toy')"
cur.execute(query)
db.commit()
cur.close()
db.close()
Raw SQL in python
● psycopg2
● written in C
● implementation of the DB API 2.0 (PEP 249)
● works like a libpq wrapper
8
Raw SQL in python
● psycopg2
● written in C
● implementation of the DB API 2.0 (PEP 249)
● works like a libpq wrapper
9
Raw SQL in python
import psycopg2
class pg_conn:
def __enter__(self):
self.conn = psycopg2.connect(
dbname='fwdays', user='highload'
)
return self.conn
def __exit__(self, exc_type, exc_val, exc_tb):
if hasattr(self, 'conn'):
self.conn.close()
10
with pg_conn() as db:
cur = db.cursor()
query = "insert into product('name') values('toy')"
cur.execute(query)
db.commit()
cur.close()
db.close()
Raw SQL in python
insert into products('name') values('toy');
11
Raw SQL in python
insert into products('name') values('toy');
select settings from application_settings
where company_id in (
3244414, 3239428, 3246756, 3215974
);
12
Raw SQL in python
13
select csa.company_id, count(csa.id)
from company_site_attributes as csa
join company as c on c.id = csa.company_id
join site_filters as csf on csf.attribute_id = csa.id
where portal_attribute_id in (1536, 17536) and
c.premium_service_id > 0 and
csa.status = 0 and
csf.status = 0
group by csa.company_id, csa.id
having count(csa.id) > 1;
Raw SQL in python
14
select csa.company_id, count(csa.id)
from company_site_attributes as csa
join company as c on c.id = csa.company_id
join site_filters as csf on csf.attribute_id = csa.id
where portal_attribute_id in (1536, 17536) and
c.premium_service_id > 0 and
csa.status = 0 and
csf.status = 0
group by csa.company_id, csa.id
having count(csa.id) > 1;
Raw SQL
● small tables
15
Raw SQL
● small tables
● few tables
16
Raw SQL
● small tables
● few tables
● no complicated types
17
Raw SQL
● small tables
● few tables
● no complicated types
● no need to manage scheme in the app
18
Raw SQL
● small tables
● few tables
● no complicated types
● no need to manage scheme in the app
● no migrations
19
Raw SQL
● small tables
● few tables
● no complicated types
● no need to manage scheme in the app
● no migrations
● no dynamic queries
20
Raw SQL
● small tables
● few tables
● no complicated types
● no need to manage scheme in the app
● no migrations
● no dynamic queries
● no app session managing
● ...
21
Python ORM
22
Python ORM
● SQLAlchemy
● Django ORM
● Peewee
● Pony ORM
● Tortoise ORM
● SQLObject
● GINO *
● ...
23
Python ORM +
● Scalability
● Security
● Trust
● Time
24
Python ORM -
● Speed
● Scope
25
SQLAlchemy
● SQLAlchemy Core
● SQLAlchemy ORM
27
28
29
30
31
32
SQLAlchemy -> asyncio
● psycopg ?
SQLAlchemy -> asyncio
● psycopg ?
AsyncIO vs SQLAlchemy
https://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/
SQLAlchemy -> asyncio
● psycopg
● aiopg
● asyncpg
aiopg vs asyncpg
https://www.youtube.com/watch?v=bY6ZU0-26TA
aiopg
psycopg
libpq
pgbouncer
postgres
asyncpg
pgbouncer
postgres
41
GraphQL
GraphQL in Python
● Graphene
● Ariadne
● Strawberry
● Hiku
Graphene
from graphene import ObjectType, String, Schema
class Query(ObjectType):
name = String(description='Name field')
formated_price = String(description='Price field')
def resolve_name(self, info):
name = get_product_name()
...
return name
def resolve_price(self, info):
price = get_product_price()
...
return format_price(price)
schema = Schema(query=Query)
query = '''
query Products {
name
price
}
'''
result = schema.execute(query)
Graphene
Base = declarative_base()
Base.query = db_session.query_property()
class ProductModel(Base):
__tablename__ = 'product'
id = Column(Integer, primary_key=True)
name = Column(String)
price = Column(Integer)
class Product(SQLAlchemyObjectType):
class Meta:
model = ProductModel
interfaces = (relay.Node, )
class Query(ObjectType):
node = relay.Node.Field()
products = SQLAlchemyConnectionField(Product)
schema = Schema(query=Query, types=[Product, ])
Graphene
query = '''
{
products {
edges {
node {
name
price
}
}
}
}
'''
Ariadne
from ariadne import ObjectType, QueryType, gql,
make_executable_schema
from ariadne.asgi import GraphQL
type_defs = gql("""
type Query {
products: [Product!]!
}
type Product {
id: Int
name: String
price: Int
}
""")
query = QueryType()
@query.field("products")
def resolve_products(*_):
...
return get_products_from_db()
product = ObjectType("Product")
@product.field("name")
def resolve_product_name(product, *_):
...
return get_product_name_from_db()
schema = make_executable_schema(type_defs, query,
product)
app = GraphQL(schema, debug=True)
Ariadne with ORM
https://github.com/mirumee/ariadne/issues/115
Hiku
from hiku.graph import Graph, Node, Link, Field, ...
from hiku.sources import sqlalchemy as sa
from hiku.types import Boolean, Integer, String, TypeRef, ...
product_query = sa.FieldsQuery('db.session', Product.table)
# product_query = asyncsa.FieldsQuery('db.session_async', Product.table)
low_level_graph = Graph([
Node('Product', [
Field('id', Integer, product_query),
Field('name', String, product_query),
Field('price', None, product_query),
...
])
query = '''
product(ids: [1234, 1235]) {
id
name
price
}
'''
"""
SELECT id, name, price FROM product
WHERE id IN (:id1, :id2, ..., :idN)
"""
Hiku
low_level_graph = Graph([
Node('Product', [
Field('id', Integer, product_query),
...
Link(
'discount',
Optional[TypeRef['Discount']],
product_to_discount_query,
requires='id',
),
]),
Node('Discount', [
Field('id', Integer, discount_query),
Field('amount', Integer, discount_query),
])
])
discount_query = sa.FieldsQuery('db.session', Discount.__table__)
"""
SELECT id, name, price, price_currency_id FROM product
WHERE id IN (:id1, :id2, ..., :idN)
"""
product_to_discount_query = sa.LinkQuery(
'db.session',
from_column=Discount.product_id,
to_column=Discount.product_id,
)
"""
SELECT product_id FROM discount
WHERE product_id IN (:id1, :id2, ..., :idN)
"""
Hiku
product_sg = SubGraph(low_level_graph, 'Product')
high_level_graph = Graph([
Node('Product', [
Field('id', String, product_sg),
Field('name', String, product_sg.compile(S.this.name)),
Field('priceText', String, product_sg.compile(
get_price_text(S.this)
)),
Field('hasDiscount', Boolean, product_sg.compile(
is_discount_available(S.this, S.this.discount)
)),
Field('discountedText', String, product_sg.compile(
get_discounted_text(S.this, S.this.discount)
)),
]),
])
@define(Record[{
'price': Float,
'price_currency_id': Integer,
'currency_settings': Any
}])
def get_price_text(product):
product_price_text = format_currency_data(
product_price,
product['price_currency_id'],
)
...
return product_price_text.formatted_number
ORM vs GraphQL
GraphQL -> EdgeDB
GraphQL -> EdgeDB
CREATE DATABASE fwdays;
START TRANSACTION;
CREATE MIGRATION catalog TO {
type Product {
required property name -> str;
property price -> int64;
required link discount -> Discount;
}
type Discount {
required property amount -> int64;
}
};
COMMIT MIGRATION movies;
COMMIT;
INSERT Product {
name := 'random name',
price := 100,
discount := (
INSERT Discount {
amount := 10,
}
)
};
INSERT Product {
name := 'another random name',
price := 200,
discount := (
SELECT Discount
FILTER
.action_id = 1234
LIMIT 1
)
};
GraphQL -> EdgeDB
SELECT Product;
SELECT Product {
name,
price
};
SELECT Product {
name,
price,
discount: {
amount
}
}
FILTER .name ILIKE '%random%';
{
Product {
name
price
}
}
{
Product(filter: {name: {eq: "random"}}) {
name
price
discount {
amount
}
}
}
ORM vs GraphQL
thnx

More Related Content

What's hot

Streams or Loops? Java 8 Stream API by Niki Petkov - Proxiad Bulgaria
Streams or Loops? Java 8 Stream API by Niki Petkov - Proxiad BulgariaStreams or Loops? Java 8 Stream API by Niki Petkov - Proxiad Bulgaria
Streams or Loops? Java 8 Stream API by Niki Petkov - Proxiad Bulgaria
HackBulgaria
 
Ruslan Shevchenko - Property based testing
Ruslan Shevchenko - Property based testingRuslan Shevchenko - Property based testing
Ruslan Shevchenko - Property based testing
Ievgenii Katsan
 
TDD and mobile development: some forgotten techniques, illustrated with Android
TDD and mobile development: some forgotten techniques, illustrated with AndroidTDD and mobile development: some forgotten techniques, illustrated with Android
TDD and mobile development: some forgotten techniques, illustrated with Android
Codemotion
 
Quickly Testing Qt Desktop Applications
Quickly Testing Qt Desktop ApplicationsQuickly Testing Qt Desktop Applications
Quickly Testing Qt Desktop Applications
Clare Macrae
 
Annotation processing tool
Annotation processing toolAnnotation processing tool
Annotation processing tool
Andrzej Ludwikowski
 
Writing testable code
Writing testable codeWriting testable code
Writing testable code
Thiago Figueredo Cardoso
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limitsDroidcon Berlin
 
Angular Weekend
Angular WeekendAngular Weekend
Angular Weekend
Troy Miles
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
Sergey Platonov
 
Golang dot-testing-lite
Golang dot-testing-liteGolang dot-testing-lite
Golang dot-testing-lite
Richárd Kovács
 
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
AvitoTech
 
Extensions vs Services: Digging Deeper - Neil Bartlett
Extensions vs Services: Digging Deeper - Neil BartlettExtensions vs Services: Digging Deeper - Neil Bartlett
Extensions vs Services: Digging Deeper - Neil Bartlett
mfrancis
 
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
Victoria Schiffer
 
My way to clean android V2
My way to clean android V2My way to clean android V2
My way to clean android V2
Christian Panadero
 
Architecture for scalable Angular applications (with introduction and extende...
Architecture for scalable Angular applications (with introduction and extende...Architecture for scalable Angular applications (with introduction and extende...
Architecture for scalable Angular applications (with introduction and extende...
Paweł Żurowski
 
The Ring programming language version 1.7 book - Part 13 of 196
The Ring programming language version 1.7 book - Part 13 of 196The Ring programming language version 1.7 book - Part 13 of 196
The Ring programming language version 1.7 book - Part 13 of 196
Mahmoud Samir Fayed
 
Advanced Swift Generics
Advanced Swift GenericsAdvanced Swift Generics
Advanced Swift Generics
Max Sokolov
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languages
Rafael Winterhalter
 
Automated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xAutomated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xTatsuya Maki
 

What's hot (19)

Streams or Loops? Java 8 Stream API by Niki Petkov - Proxiad Bulgaria
Streams or Loops? Java 8 Stream API by Niki Petkov - Proxiad BulgariaStreams or Loops? Java 8 Stream API by Niki Petkov - Proxiad Bulgaria
Streams or Loops? Java 8 Stream API by Niki Petkov - Proxiad Bulgaria
 
Ruslan Shevchenko - Property based testing
Ruslan Shevchenko - Property based testingRuslan Shevchenko - Property based testing
Ruslan Shevchenko - Property based testing
 
TDD and mobile development: some forgotten techniques, illustrated with Android
TDD and mobile development: some forgotten techniques, illustrated with AndroidTDD and mobile development: some forgotten techniques, illustrated with Android
TDD and mobile development: some forgotten techniques, illustrated with Android
 
Quickly Testing Qt Desktop Applications
Quickly Testing Qt Desktop ApplicationsQuickly Testing Qt Desktop Applications
Quickly Testing Qt Desktop Applications
 
Annotation processing tool
Annotation processing toolAnnotation processing tool
Annotation processing tool
 
Writing testable code
Writing testable codeWriting testable code
Writing testable code
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limits
 
Angular Weekend
Angular WeekendAngular Weekend
Angular Weekend
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
 
Golang dot-testing-lite
Golang dot-testing-liteGolang dot-testing-lite
Golang dot-testing-lite
 
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
 
Extensions vs Services: Digging Deeper - Neil Bartlett
Extensions vs Services: Digging Deeper - Neil BartlettExtensions vs Services: Digging Deeper - Neil Bartlett
Extensions vs Services: Digging Deeper - Neil Bartlett
 
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
Agile Developer Immersion Workshop, LASTconf Melbourne, Australia, 19th July ...
 
My way to clean android V2
My way to clean android V2My way to clean android V2
My way to clean android V2
 
Architecture for scalable Angular applications (with introduction and extende...
Architecture for scalable Angular applications (with introduction and extende...Architecture for scalable Angular applications (with introduction and extende...
Architecture for scalable Angular applications (with introduction and extende...
 
The Ring programming language version 1.7 book - Part 13 of 196
The Ring programming language version 1.7 book - Part 13 of 196The Ring programming language version 1.7 book - Part 13 of 196
The Ring programming language version 1.7 book - Part 13 of 196
 
Advanced Swift Generics
Advanced Swift GenericsAdvanced Swift Generics
Advanced Swift Generics
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languages
 
Automated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xAutomated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.x
 

Similar to ORM vs GraphQL - Python fwdays 2019

How to grow GraphQL and remove SQLAlchemy and REST API from a high-load Pytho...
How to grow GraphQL and remove SQLAlchemy and REST API from a high-load Pytho...How to grow GraphQL and remove SQLAlchemy and REST API from a high-load Pytho...
How to grow GraphQL and remove SQLAlchemy and REST API from a high-load Pytho...
Oleksandr Tarasenko
 
Relational Database Access with Python ‘sans’ ORM
Relational Database Access with Python ‘sans’ ORM  Relational Database Access with Python ‘sans’ ORM
Relational Database Access with Python ‘sans’ ORM
Mark Rees
 
Adding replication protocol support for psycopg2
Adding replication protocol support for psycopg2Adding replication protocol support for psycopg2
Adding replication protocol support for psycopg2
Alexander Shulgin
 
Relational Database Access with Python
Relational Database Access with PythonRelational Database Access with Python
Relational Database Access with Python
Mark Rees
 
GraphQL IN Golang
GraphQL IN GolangGraphQL IN Golang
GraphQL IN Golang
Bo-Yi Wu
 
Twins: OOP and FP
Twins: OOP and FPTwins: OOP and FP
Twins: OOP and FP
RichardWarburton
 
HashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin InfrastructureHashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin Infrastructure
Nicolas Corrarello
 
React inter3
React inter3React inter3
React inter3
Oswald Campesato
 
GraphQL the holy contract between client and server
GraphQL the holy contract between client and serverGraphQL the holy contract between client and server
GraphQL the holy contract between client and server
Pavel Chertorogov
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
Python Ireland
 
Refactoring for testability c++
Refactoring for testability c++Refactoring for testability c++
Refactoring for testability c++
Dimitrios Platis
 
Go Is Your Next Language — Sergii Shapoval
Go Is Your Next Language — Sergii ShapovalGo Is Your Next Language — Sergii Shapoval
Go Is Your Next Language — Sergii Shapoval
GlobalLogic Ukraine
 
SPRAT - Spreadsheet API Tester
SPRAT - Spreadsheet API TesterSPRAT - Spreadsheet API Tester
SPRAT - Spreadsheet API Tester
Julian Higman
 
The Ring programming language version 1.5.2 book - Part 10 of 181
The Ring programming language version 1.5.2 book - Part 10 of 181The Ring programming language version 1.5.2 book - Part 10 of 181
The Ring programming language version 1.5.2 book - Part 10 of 181
Mahmoud Samir Fayed
 
How to separate frontend from a highload python project with no problems - Py...
How to separate frontend from a highload python project with no problems - Py...How to separate frontend from a highload python project with no problems - Py...
How to separate frontend from a highload python project with no problems - Py...
Oleksandr Tarasenko
 
Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in C
Steffen Wenz
 
Everything as a Code / Александр Тарасов (Одноклассники)
Everything as a Code / Александр Тарасов (Одноклассники)Everything as a Code / Александр Тарасов (Одноклассники)
Everything as a Code / Александр Тарасов (Одноклассники)
Ontico
 
Everything as a code
Everything as a codeEverything as a code
Everything as a code
Aleksandr Tarasov
 
All things that are not code
All things that are not codeAll things that are not code
All things that are not code
Mobile Delivery Days
 
Angular2 inter3
Angular2 inter3Angular2 inter3
Angular2 inter3
Oswald Campesato
 

Similar to ORM vs GraphQL - Python fwdays 2019 (20)

How to grow GraphQL and remove SQLAlchemy and REST API from a high-load Pytho...
How to grow GraphQL and remove SQLAlchemy and REST API from a high-load Pytho...How to grow GraphQL and remove SQLAlchemy and REST API from a high-load Pytho...
How to grow GraphQL and remove SQLAlchemy and REST API from a high-load Pytho...
 
Relational Database Access with Python ‘sans’ ORM
Relational Database Access with Python ‘sans’ ORM  Relational Database Access with Python ‘sans’ ORM
Relational Database Access with Python ‘sans’ ORM
 
Adding replication protocol support for psycopg2
Adding replication protocol support for psycopg2Adding replication protocol support for psycopg2
Adding replication protocol support for psycopg2
 
Relational Database Access with Python
Relational Database Access with PythonRelational Database Access with Python
Relational Database Access with Python
 
GraphQL IN Golang
GraphQL IN GolangGraphQL IN Golang
GraphQL IN Golang
 
Twins: OOP and FP
Twins: OOP and FPTwins: OOP and FP
Twins: OOP and FP
 
HashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin InfrastructureHashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin Infrastructure
 
React inter3
React inter3React inter3
React inter3
 
GraphQL the holy contract between client and server
GraphQL the holy contract between client and serverGraphQL the holy contract between client and server
GraphQL the holy contract between client and server
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
 
Refactoring for testability c++
Refactoring for testability c++Refactoring for testability c++
Refactoring for testability c++
 
Go Is Your Next Language — Sergii Shapoval
Go Is Your Next Language — Sergii ShapovalGo Is Your Next Language — Sergii Shapoval
Go Is Your Next Language — Sergii Shapoval
 
SPRAT - Spreadsheet API Tester
SPRAT - Spreadsheet API TesterSPRAT - Spreadsheet API Tester
SPRAT - Spreadsheet API Tester
 
The Ring programming language version 1.5.2 book - Part 10 of 181
The Ring programming language version 1.5.2 book - Part 10 of 181The Ring programming language version 1.5.2 book - Part 10 of 181
The Ring programming language version 1.5.2 book - Part 10 of 181
 
How to separate frontend from a highload python project with no problems - Py...
How to separate frontend from a highload python project with no problems - Py...How to separate frontend from a highload python project with no problems - Py...
How to separate frontend from a highload python project with no problems - Py...
 
Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in C
 
Everything as a Code / Александр Тарасов (Одноклассники)
Everything as a Code / Александр Тарасов (Одноклассники)Everything as a Code / Александр Тарасов (Одноклассники)
Everything as a Code / Александр Тарасов (Одноклассники)
 
Everything as a code
Everything as a codeEverything as a code
Everything as a code
 
All things that are not code
All things that are not codeAll things that are not code
All things that are not code
 
Angular2 inter3
Angular2 inter3Angular2 inter3
Angular2 inter3
 

Recently uploaded

Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
XfilesPro
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
Jelle | Nordend
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Visitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.appVisitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.app
NaapbooksPrivateLimi
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
WSO2
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
IES VE
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
Cyanic lab
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
XfilesPro
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
Peter Caitens
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Natan Silnitsky
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
KrzysztofKkol1
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
kalichargn70th171
 

Recently uploaded (20)

Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Visitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.appVisitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.app
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
 

ORM vs GraphQL - Python fwdays 2019

  • 1. ORM vs GraphQL Oleksandr Tarasenko EVO.company / prom.ua
  • 2. Agenda ● Raw SQL in python ● Python ORM libs ● async/await and ORM solutions ● GraphQL implementation 2
  • 4. 4
  • 5. 5
  • 7. Raw SQL in python import psycopg2 class pg_conn: def __enter__(self): self.conn = psycopg2.connect( dbname='fwdays', user='highload' ) return self.conn def __exit__(self, exc_type, exc_val, exc_tb): if hasattr(self, 'conn'): self.conn.close() 7 with pg_conn() as db: cur = db.cursor() query = "insert into product('name') values('toy')" cur.execute(query) db.commit() cur.close() db.close()
  • 8. Raw SQL in python ● psycopg2 ● written in C ● implementation of the DB API 2.0 (PEP 249) ● works like a libpq wrapper 8
  • 9. Raw SQL in python ● psycopg2 ● written in C ● implementation of the DB API 2.0 (PEP 249) ● works like a libpq wrapper 9
  • 10. Raw SQL in python import psycopg2 class pg_conn: def __enter__(self): self.conn = psycopg2.connect( dbname='fwdays', user='highload' ) return self.conn def __exit__(self, exc_type, exc_val, exc_tb): if hasattr(self, 'conn'): self.conn.close() 10 with pg_conn() as db: cur = db.cursor() query = "insert into product('name') values('toy')" cur.execute(query) db.commit() cur.close() db.close()
  • 11. Raw SQL in python insert into products('name') values('toy'); 11
  • 12. Raw SQL in python insert into products('name') values('toy'); select settings from application_settings where company_id in ( 3244414, 3239428, 3246756, 3215974 ); 12
  • 13. Raw SQL in python 13 select csa.company_id, count(csa.id) from company_site_attributes as csa join company as c on c.id = csa.company_id join site_filters as csf on csf.attribute_id = csa.id where portal_attribute_id in (1536, 17536) and c.premium_service_id > 0 and csa.status = 0 and csf.status = 0 group by csa.company_id, csa.id having count(csa.id) > 1;
  • 14. Raw SQL in python 14 select csa.company_id, count(csa.id) from company_site_attributes as csa join company as c on c.id = csa.company_id join site_filters as csf on csf.attribute_id = csa.id where portal_attribute_id in (1536, 17536) and c.premium_service_id > 0 and csa.status = 0 and csf.status = 0 group by csa.company_id, csa.id having count(csa.id) > 1;
  • 15. Raw SQL ● small tables 15
  • 16. Raw SQL ● small tables ● few tables 16
  • 17. Raw SQL ● small tables ● few tables ● no complicated types 17
  • 18. Raw SQL ● small tables ● few tables ● no complicated types ● no need to manage scheme in the app 18
  • 19. Raw SQL ● small tables ● few tables ● no complicated types ● no need to manage scheme in the app ● no migrations 19
  • 20. Raw SQL ● small tables ● few tables ● no complicated types ● no need to manage scheme in the app ● no migrations ● no dynamic queries 20
  • 21. Raw SQL ● small tables ● few tables ● no complicated types ● no need to manage scheme in the app ● no migrations ● no dynamic queries ● no app session managing ● ... 21
  • 23. Python ORM ● SQLAlchemy ● Django ORM ● Peewee ● Pony ORM ● Tortoise ORM ● SQLObject ● GINO * ● ... 23
  • 24. Python ORM + ● Scalability ● Security ● Trust ● Time 24
  • 25. Python ORM - ● Speed ● Scope 25
  • 26.
  • 28. 28
  • 29. 29
  • 30. 30
  • 31. 31
  • 32. 32
  • 33.
  • 34.
  • 38. SQLAlchemy -> asyncio ● psycopg ● aiopg ● asyncpg
  • 42. GraphQL in Python ● Graphene ● Ariadne ● Strawberry ● Hiku
  • 43. Graphene from graphene import ObjectType, String, Schema class Query(ObjectType): name = String(description='Name field') formated_price = String(description='Price field') def resolve_name(self, info): name = get_product_name() ... return name def resolve_price(self, info): price = get_product_price() ... return format_price(price) schema = Schema(query=Query) query = ''' query Products { name price } ''' result = schema.execute(query)
  • 44. Graphene Base = declarative_base() Base.query = db_session.query_property() class ProductModel(Base): __tablename__ = 'product' id = Column(Integer, primary_key=True) name = Column(String) price = Column(Integer) class Product(SQLAlchemyObjectType): class Meta: model = ProductModel interfaces = (relay.Node, ) class Query(ObjectType): node = relay.Node.Field() products = SQLAlchemyConnectionField(Product) schema = Schema(query=Query, types=[Product, ])
  • 45. Graphene query = ''' { products { edges { node { name price } } } } '''
  • 46. Ariadne from ariadne import ObjectType, QueryType, gql, make_executable_schema from ariadne.asgi import GraphQL type_defs = gql(""" type Query { products: [Product!]! } type Product { id: Int name: String price: Int } """) query = QueryType() @query.field("products") def resolve_products(*_): ... return get_products_from_db() product = ObjectType("Product") @product.field("name") def resolve_product_name(product, *_): ... return get_product_name_from_db() schema = make_executable_schema(type_defs, query, product) app = GraphQL(schema, debug=True)
  • 48. Hiku from hiku.graph import Graph, Node, Link, Field, ... from hiku.sources import sqlalchemy as sa from hiku.types import Boolean, Integer, String, TypeRef, ... product_query = sa.FieldsQuery('db.session', Product.table) # product_query = asyncsa.FieldsQuery('db.session_async', Product.table) low_level_graph = Graph([ Node('Product', [ Field('id', Integer, product_query), Field('name', String, product_query), Field('price', None, product_query), ... ]) query = ''' product(ids: [1234, 1235]) { id name price } ''' """ SELECT id, name, price FROM product WHERE id IN (:id1, :id2, ..., :idN) """
  • 49. Hiku low_level_graph = Graph([ Node('Product', [ Field('id', Integer, product_query), ... Link( 'discount', Optional[TypeRef['Discount']], product_to_discount_query, requires='id', ), ]), Node('Discount', [ Field('id', Integer, discount_query), Field('amount', Integer, discount_query), ]) ]) discount_query = sa.FieldsQuery('db.session', Discount.__table__) """ SELECT id, name, price, price_currency_id FROM product WHERE id IN (:id1, :id2, ..., :idN) """ product_to_discount_query = sa.LinkQuery( 'db.session', from_column=Discount.product_id, to_column=Discount.product_id, ) """ SELECT product_id FROM discount WHERE product_id IN (:id1, :id2, ..., :idN) """
  • 50. Hiku product_sg = SubGraph(low_level_graph, 'Product') high_level_graph = Graph([ Node('Product', [ Field('id', String, product_sg), Field('name', String, product_sg.compile(S.this.name)), Field('priceText', String, product_sg.compile( get_price_text(S.this) )), Field('hasDiscount', Boolean, product_sg.compile( is_discount_available(S.this, S.this.discount) )), Field('discountedText', String, product_sg.compile( get_discounted_text(S.this, S.this.discount) )), ]), ]) @define(Record[{ 'price': Float, 'price_currency_id': Integer, 'currency_settings': Any }]) def get_price_text(product): product_price_text = format_currency_data( product_price, product['price_currency_id'], ) ... return product_price_text.formatted_number
  • 53. GraphQL -> EdgeDB CREATE DATABASE fwdays; START TRANSACTION; CREATE MIGRATION catalog TO { type Product { required property name -> str; property price -> int64; required link discount -> Discount; } type Discount { required property amount -> int64; } }; COMMIT MIGRATION movies; COMMIT; INSERT Product { name := 'random name', price := 100, discount := ( INSERT Discount { amount := 10, } ) }; INSERT Product { name := 'another random name', price := 200, discount := ( SELECT Discount FILTER .action_id = 1234 LIMIT 1 ) };
  • 54. GraphQL -> EdgeDB SELECT Product; SELECT Product { name, price }; SELECT Product { name, price, discount: { amount } } FILTER .name ILIKE '%random%'; { Product { name price } } { Product(filter: {name: {eq: "random"}}) { name price discount { amount } } }
  • 56. thnx