SlideShare une entreprise Scribd logo
1  sur  37
Télécharger pour lire hors ligne
Relational Database Access
with Python
Why you should be using SQLAlchemy
Mark Rees
CTO
Century Software (M) Sdn. Bhd.
Is This Your Current Relational Database Access
Style?
# Django ORM
>>> from ip2country.models import Ip2Country
>>> Ip2Country.objects.all()
[<Ip2Country: Ip2Country object>, <Ip2Country: Ip2Country
object>, '...(remaining elements truncated)...']
>>> myp = Ip2Country.objects.filter(assigned__year=2015)
... .filter(countrycode2=’MY')
>>> myp[0].ipfrom
736425984.0
Is This Your Current Relational Database Access
Style?
# SQLAlchemy ORM
>>> from sqlalchemy import create_engine, extract
>>> from sqlalchemy.orm import sessionmaker
>>> from models import Ip2Country
>>> engine =
create_engine('postgresql://ip2country_rw:secret@localhost/i
p2country')
>>> Session = sessionmaker(bind=engine)
>>> session = Session()
>>> all_data = session.query(Ip2Country).all()
>>> myp = session.query(Ip2Country).
... filter(extract('year',Ip2Country.assigned) == 2015).
... filter(Ip2Country.countrycode2 == ’MY')
print(myp[0].ipfrom)
736425984.0
SQL Relational Database Access
SELECT * FROM ip2country;
“id”,"ipfrom";"ipto";"registry";"assigned";"countrycode2";"countrycode3";"countryname"
1,1729522688;1729523711;"apnic";"2011-08-05";"CN";"CHN";"China"
2,1729523712;1729524735;"apnic";"2011-08-05";"CN";"CHN";"China”
. . .
SELECT * FROM ip2country
WHERE date_part('year', assigned) = 2015
AND countrycode2 = ’MY';
“id”,"ipfrom";"ipto";"registry";"assigned";"countrycode2";"countrycode3";"countryname"
5217;736425984;736427007;"apnic";"2015-01-13 00:00:00";"MY";"MYS";"Malaysia”
5218;736427008;736428031;"apnic";"2015-01-13 00:00:00";"MY";"MYS";"Malaysia”
. . .
SELECT ipfrom FROM ip2country
WHERE date_part('year', assigned) = 2015
AND countrycode2 = ’MY';
"ipfrom"
736425984
736427008
. . .
Python + SQL == Python DB-API 2.0
• The Python standard for a consistent
interface to relational databases is the
Python DB-API (PEP 249)
• The majority of Python database interfaces
adhere to this standard
Python DB-API UML Diagram
Python DB-API Connection Object
Access the database via the connection object
• Use connect constructor to create a
connection with database
conn = psycopg2.connect(parameters…)
• Create cursor via the connection
cur = conn.cursor()
• Transaction management (implicit begin)
conn.commit()
conn.rollback()
• Close connection (will rollback current
transaction)
conn.close()
• Check module capabilities by globals
psycopg2.apilevel psycopg2.threadsafety
psycopg2.paramstyle
Python DB-API Cursor Object
A cursor object is used to represent a database
cursor, which is used to manage the context of
fetch operations.
• Cursors created from the same connection
are not isolated
cur = conn.cursor()
cur2 = conn.cursor()
• Cursor methods
cur.execute(operation, parameters)
cur.executemany(op,seq_of_parameters)
cur.fetchone()
cur.fetchmany([size=cursor.arraysize])
cur.fetchall()
cur.close()
Python DB-API Cursor Object
• Optional cursor methods
cur.scroll(value[,mode='relative'])
cur.next()
cur.callproc(procname[,parameters])
cur.__iter__()
• Results of an operation
cur.description
cur.rowcount
cur.lastrowid
• DB adaptor specific “proprietary” cursor
methods
Python DB-API Parameter Styles
Allows you to keep SQL separate from parameters
Improves performance & security
Warning Never, never, NEVER use Python string
concatenation (+) or string parameters
interpolation (%) to pass variables to a SQL query
string. Not even at gunpoint.
From http://initd.org/psycopg/docs/usage.html#query-parameters
Python DB-API Parameter Styles
Global paramstyle gives supported style for the
adaptor
qmark Question mark style
WHERE countrycode2 = ?
numeric Numeric positional style
WHERE countrycode2 = :1
named Named style
WHERE countrycode2 = :code
format ANSI C printf format style
WHERE countrycode2 = %s
pyformat Python format style
WHERE countrycode2 = %(name)s
Python + SQL: INSERT
import csv, datetime, psycopg2
conn = psycopg2.connect("dbname=ip2countrydb user=ip2country_rw
password=secret")
cur = conn.cursor()
with open("IpToCountry.csv", "rt") as f:
reader = csv.reader(f)
try:
for row in reader:
if row[0][0] != "#":
row[3] =
datetime.datetime.utcfromtimestamp(float(row[3]))
cur.execute("""INSERT INTO ip2country(
ipfrom, ipto, registry, assigned,
countrycode2, countrycode3, countryname)
VALUES (%s, %s, %s, %s, %s, %s, %s)""", row)
except (Exception) as error:
print(error)
conn.rollback()
else:
conn.commit()
finally:
cur.close()
conn.close()
Python + SQL: SELECT
# Find ipv4 address ranges assigned to Malaysia
import psycopg2, socket, struct
def num_to_dotted_quad(n):
"""convert long int to dotted quad string
http://code.activestate.com/recipes/66517/"""
return socket.inet_ntoa(struct.pack('!L', n))
conn = psycopg2.connect("dbname=ip2countrydb user=ip2country_rw
password=secret")
cur = conn.cursor()
cur.execute("""SELECT * FROM ip2country
WHERE countrycode2 = 'MY'
ORDER BY ipfrom""")
for row in cur:
print("%s - %s" % (num_to_dotted_quad(int(row[0])),
num_to_dotted_quad(int(row[1]))))
SQLite
• sqlite3
• CPython 2.5 & 3
• DB-API 2.0
• Part of CPython distribution since 2.5
PostgreSQL
• psycopg
• CPython 2 & 3
• DB-API 2.0, level 2 thread safe
• Appears to be most popular
• http://initd.org/psycopg/
• py-postgresql
• CPython 3
• DB-API 2.0
• Written in Python with optional C
optimizations
• pg_python - console
• http://python.projects.postgresql.org/
PostgreSQL
• PyGreSQL
• CPython 2.5+
• Classic & DB-API 2.0 interfaces
• http://www.pygresql.org/
• pyPgSQL
• CPython 2
• Classic & DB-API 2.0 interfaces
• http://pypgsql.sourceforge.net/
• Last release 2006
PostgreSQL
• pypq
• CPython 2.7 & pypy 1.7+
• Uses ctypes
• DB-API 2.0 interface
• psycopg2-like extension API
• https://bitbucket.org/descent/pypq
• psycopg2cffi
• CPython 2.6+ & pypy 2.0+
• Uses cffi
• DB-API 2.0 interface
• psycopg2 compat layer
• https://github.com/chtd/psycopg2cffi
MySQL
• MySQL-python
• CPython 2.3+
• DB-API 2.0 interface
• http://sourceforge.net/projects/mysql-
python/
• PyMySQL
• CPython 2.4+ & 3
• Pure Python DB-API 2.0 interface
• http://www.pymysql.org/
• MySQL-Connector
• CPython 2.4+ & 3
• Pure Python DB-API 2.0 interface
• https://launchpad.net/myconnpy
Other “Enterprise” Databases
• cx_Oracle
• CPython 2 & 3
• DB-API 2.0 interface
• http://cx-oracle.sourceforge.net/
• informixda
• CPython 2
• DB-API 2.0 interface
• http://informixdb.sourceforge.net/
• Last release 2007
• Ibm-db
• CPython 2
• DB-API 2.0 for DB2 & Informix
• http://code.google.com/p/ibm-db/
ODBC
• mxODBC
• CPython 2.3+
• DB-API 2.0 interfaces
• http://www.egenix.com/products/pytho
n/mxODBC/doc
• Commercial product
• PyODBC
• CPython 2 & 3
• DB-API 2.0 interfaces with extensions
• https://github.com/mkleehammer/pyod
bc
• ODBC interfaces not limited to Windows
thanks to iODBC and unixODBC
Jython + SQL
• zxJDBC
• DB-API 2.0 Written in Java using JDBC API
so can utilize JDBC drivers
• Support for connection pools and JNDI
lookup
• Included with standard Jython
installation http://www.jython.org/
• jyjdbc
• DB-API 2.0 compliant
• Written in Python/Jython so can utilize
JDBC drivers
• Decimal data type support
• https://bitbucket.org/clach04/jyjdbc/
IronPython + SQL
• adodbapi
• IronPython 2+
• Also works with CPython 2.3+ with
pywin32
• http://adodbapi.sourceforge.net/
Gerald, the half a schema
import gerald
s1 = gerald.PostgresSchema(’public',
'postgres://ip2country_rw:secret@localhost/ip2country')
s2 = gerald.PostgresSchema(’public',
'postgres://ip2country_rw:secret@localhost/ip2countryv4')
print s1.schema['ip2country'].compare(s2.schema['ip2country'])
DIFF: Definition of assigned is different
DIFF: Column countryname not in ip2country
DIFF: Definition of registry is different
DIFF: Column countrycode3 not in ip2country
DIFF: Definition of countrycode2 is different
• Database schema toolkit
• via DB-API currently supports
• PostgreSQL
• MySQL
• Oracle
• http://halfcooked.com/code/gerald/
SQLPython
$ sqlpython --postgresql ip2country ip2country_rw
Password:
0:ip2country_rw@ip2country> select * from ip2country where countrycode2='SG';
...
1728830464.0 1728830719.0 apnic 2011-11-02 SG SGP Singapore
551 rows selected.
0:ip2country_rw@ip2country> select * from ip2country where countrycode2='SG'j
[...
{"ipfrom": 1728830464.0, "ipto": 1728830719.0, "registry": "apnic”,"assigned":
"2011-11-02", "countrycode2": "SG", "countrycode3": "SGP", "countryname":
"Singapore"}]
• A command-line interface to relational
databases
• via DB-API currently supports
• PostgreSQL
• MySQL
• Oracle
• http://packages.python.org/sqlpython/
SQLPython, batteries included
0:ip2country_rw@ip2country> select * from ip2country where countrycode2 =’MY’;
...
1728830464.0 1728830719.0 apnic 2011-11-02 MY MYS Malaysia
551 rows selected.
0:ip2country_rw@ip2country> py
Python 2.6.6 (r266:84292, May 20 2011, 16:42:25)
[GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2
py <command>: Executes a Python command.
py: Enters interactive Python mode.
End with `Ctrl-D` (Unix) / `Ctrl-Z` (Windows), `quit()`, 'exit()`.
Past SELECT results are exposed as list `r`;
most recent resultset is `r[-1]`.
SQL bind, substitution variables are exposed as `binds`, `substs`.
Run python code from external files with ``run("filename.py")``
>>> r[-1][-1]
(1728830464.0, 1728830719.0, 'apnic', datetime.date(2011, 11, 2), ’MY', ’MYS',
’Malaysia')
>>> import socket, struct
>>> def num_to_dotted_quad(n):
... return socket.inet_ntoa(struct.pack('!L',n))
...
>>> num_to_dotted_quad(int(r[-1][-1].ipfrom))
'103.11.220.0'
SpringPython – Database Templates
# Find ipv4 address ranges assigned to Malaysia
# using SpringPython DatabaseTemplate & DictionaryRowMapper
from springpython.database.core import *
from springpython.database.factory import *
conn_factory = PgdbConnectionFactory(
user="ip2country_rw", password="secret",
host="localhost", database="ip2countrydb")
dt = DatabaseTemplate(conn_factory)
results = dt.query(
"SELECT * FROM ip2country WHERE countrycode2=%s",
(”MY",), DictionaryRowMapper())
for row in results:
print("%s - %s" % (num_to_dotted_quad(int(row['ipfrom'])),
num_to_dotted_quad(int(row['ipto']))))
SQLAlchemy
http://www.sqlalchemy.org/
First release in 2005
Now at version 1.0.8
What is it
• Provides helpers, tools & components to
assist with database access
• Provides a consisdent and full featured
façade over the Python DBAPI
• Provides an optional object relational
mapper(ORM)
• Foundation for many Python third party
libraries & tools
• It doesn’t hide the database, you need
understand SQL
SQLAlchemy Overview
SQLAlchemy Core – The Engine
from sqlalchemy import create_engine
engine =
create_engine('postgresql://ip2country_rw:secret@localhost/i
p2countrydb')
engine.execute("""
create table registry (
id serial primary key,
name text
)
""")
engine.execute("""
insert into registry(name) values('apnic')
""")
engine.execute("""
insert into registry(name) values('aprn')
""”)
engine.execute("""
insert into registry(name) values('lacnic')
""")
SQLAlchemy Core – SQL Expression Language
from sqlalchemy import create_engine, Table, Column, Integer, String,
MetaData
engine =
create_engine('postgresql://ip2country_rw:secret@localhost/ip2countrydb',
echo=True)
metadata = MetaData()
registry = Table('registry', metadata,
Column('id', Integer,
autoincrement=True,
primary_key=True),
Column('name', String(10)))
metadata.create_all(engine) # create table if it doesn't exist
# auto construct insert statement with binding parameters
ins = registry.insert().values(name='dummy’)
conn = engine.connect() # get database connection
# insert multiple rows with explicit commit
conn.execute(ins, [{'name': 'apnic'},
{'name': 'aprn'}, {'name': 'lacnic'}])
SQLAlchemy Core – SQL Expression Language
from sqlalchemy import create_engine, Table, Column, Integer, String,
MetaData
from sqlalchemy.sql import select
engine =
create_engine('postgresql://ip2country_rw:secret@localhost/ip2countrydb',
echo=True)
metadata = MetaData()
registry = Table('registry', metadata,
Column('id', Integer, autoincrement=True,
primary_key=True,
Column('name', String(10)))
# auto create select statement
s = select([registry])
conn = engine.connect()
result = conn.execute(s)
for row in result:
print(row)
SQLAlchemy Core – SQL Expression Language
from sqlalchemy import create_engine, Table, Column, Integer, String,
MetaData
from sqlalchemy.sql import select
engine =
create_engine('postgresql://ip2country_rw:secret@localhost/ip2countrydb',
echo=True)
metadata = MetaData()
registry = Table('registry', metadata,
Column('id', Integer, autoincrement=True,
primary_key=True,
Column('name', String(10)))
# auto create select statement
s = select([registry])
conn = engine.connect()
result = conn.execute(s)
for row in result:
print(row)
SQLAlchemy ORM
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Table, Column, Integer, String
Base = declarative_base()
class Registry(Base):
__tablename__ = 'registry'
id = Column(Integer, autoincrement=True, primary_key=True)
name = Column(String(10))
def __repr__(self):
return "<Registry(%r, %r)>" % (
self.id, self.name
)
engine =
create_engine('postgresql://ip2country_rw:secret@localhost/ip2countrydb',
echo=True)
Base.metadata.create_all(engine)
from sqlalchemy.orm import Session
session = Session(bind=engine)
apnic = session.query(Registry).filter_by(name='apnic').first()
print(apnic)
SQLAlchemy ORM
. . .
Base = declarative_base()
class Registry(Base):
__tablename__ = 'registry'
id = Column(Integer, autoincrement=True, primary_key=True)
name = Column(String(10))
def __repr__(self):
return "<Registry(%r, %r)>" % (
self.id, self.name
)
engine =
create_engine('postgresql://ip2country_rw:secret@localhost/ip2countrydb',
echo=True)
Base.metadata.create_all(engine)
from sqlalchemy.orm import Session
session = Session(bind=engine)
mynic = Registry(name='mynic')
session.add(mynic)
DB-API 2.0 PEP
http://www.python.org/dev/peps/pep-0249/
Travis Spencer’s DB-API UML Diagram
http://travisspencer.com/
Andrew Kuchling's introduction to the DB-API
http://www.amk.ca/python/writing/DB-API.html
Attributions
Andy Todd’s OSDC paper
http://halfcooked.com/presentations/osdc2006/p
ython_databases.html
Source of csv data used in examples from
WebNet77 licensed under GPLv3
http://software77.net/geo-ip/
Attributions
Mark Rees
mark at censof dot com
+Mark Rees
@hexdump42
hex-dump.blogspot.com
Contact Details

Contenu connexe

Tendances

Angular JS deep dive
Angular JS deep diveAngular JS deep dive
Angular JS deep diveAxilis
 
Enabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseEnabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseDataStax Academy
 
Administering and Monitoring SolrCloud Clusters
Administering and Monitoring SolrCloud ClustersAdministering and Monitoring SolrCloud Clusters
Administering and Monitoring SolrCloud Clusterslucenerevolution
 
Developing distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterDeveloping distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterKonstantin Tsykulenko
 
Pycon 2012 Apache Cassandra
Pycon 2012 Apache CassandraPycon 2012 Apache Cassandra
Pycon 2012 Apache Cassandrajeremiahdjordan
 
DataStax: An Introduction to DataStax Enterprise Search
DataStax: An Introduction to DataStax Enterprise SearchDataStax: An Introduction to DataStax Enterprise Search
DataStax: An Introduction to DataStax Enterprise SearchDataStax Academy
 
Cassandra 3.0 Awesomeness
Cassandra 3.0 AwesomenessCassandra 3.0 Awesomeness
Cassandra 3.0 AwesomenessJon Haddad
 
Advanced data access with Dapper
Advanced data access with DapperAdvanced data access with Dapper
Advanced data access with DapperDavid Paquette
 
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDBPuppet Camp Melbourne 2014: Node Collaboration with PuppetDB
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDBPuppet
 
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Sunghyouk Bae
 
Create & Execute First Hadoop MapReduce Project in.pptx
Create & Execute First Hadoop MapReduce Project in.pptxCreate & Execute First Hadoop MapReduce Project in.pptx
Create & Execute First Hadoop MapReduce Project in.pptxvishal choudhary
 
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB Puppet
 
Manchester Hadoop Meetup: Cassandra Spark internals
Manchester Hadoop Meetup: Cassandra Spark internalsManchester Hadoop Meetup: Cassandra Spark internals
Manchester Hadoop Meetup: Cassandra Spark internalsChristopher Batey
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentationGene Chang
 
Python SQite3 database Tutorial | SQlite Database
Python SQite3 database Tutorial | SQlite DatabasePython SQite3 database Tutorial | SQlite Database
Python SQite3 database Tutorial | SQlite DatabaseElangovanTechNotesET
 
Elasticsearch - Dynamic Nodes
Elasticsearch - Dynamic NodesElasticsearch - Dynamic Nodes
Elasticsearch - Dynamic NodesScott Davis
 
Effective testing for spark programs Strata NY 2015
Effective testing for spark programs   Strata NY 2015Effective testing for spark programs   Strata NY 2015
Effective testing for spark programs Strata NY 2015Holden Karau
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Sunghyouk Bae
 

Tendances (20)

Dapper performance
Dapper performanceDapper performance
Dapper performance
 
Angular JS deep dive
Angular JS deep diveAngular JS deep dive
Angular JS deep dive
 
Enabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseEnabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax Enterprise
 
Administering and Monitoring SolrCloud Clusters
Administering and Monitoring SolrCloud ClustersAdministering and Monitoring SolrCloud Clusters
Administering and Monitoring SolrCloud Clusters
 
Dapper
DapperDapper
Dapper
 
Developing distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterDeveloping distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka Cluster
 
Pycon 2012 Apache Cassandra
Pycon 2012 Apache CassandraPycon 2012 Apache Cassandra
Pycon 2012 Apache Cassandra
 
DataStax: An Introduction to DataStax Enterprise Search
DataStax: An Introduction to DataStax Enterprise SearchDataStax: An Introduction to DataStax Enterprise Search
DataStax: An Introduction to DataStax Enterprise Search
 
Cassandra 3.0 Awesomeness
Cassandra 3.0 AwesomenessCassandra 3.0 Awesomeness
Cassandra 3.0 Awesomeness
 
Advanced data access with Dapper
Advanced data access with DapperAdvanced data access with Dapper
Advanced data access with Dapper
 
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDBPuppet Camp Melbourne 2014: Node Collaboration with PuppetDB
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB
 
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
 
Create & Execute First Hadoop MapReduce Project in.pptx
Create & Execute First Hadoop MapReduce Project in.pptxCreate & Execute First Hadoop MapReduce Project in.pptx
Create & Execute First Hadoop MapReduce Project in.pptx
 
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB
Puppet Camp Melbourne 2014: Node Collaboration with PuppetDB
 
Manchester Hadoop Meetup: Cassandra Spark internals
Manchester Hadoop Meetup: Cassandra Spark internalsManchester Hadoop Meetup: Cassandra Spark internals
Manchester Hadoop Meetup: Cassandra Spark internals
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentation
 
Python SQite3 database Tutorial | SQlite Database
Python SQite3 database Tutorial | SQlite DatabasePython SQite3 database Tutorial | SQlite Database
Python SQite3 database Tutorial | SQlite Database
 
Elasticsearch - Dynamic Nodes
Elasticsearch - Dynamic NodesElasticsearch - Dynamic Nodes
Elasticsearch - Dynamic Nodes
 
Effective testing for spark programs Strata NY 2015
Effective testing for spark programs   Strata NY 2015Effective testing for spark programs   Strata NY 2015
Effective testing for spark programs Strata NY 2015
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017
 

En vedette

Michael Bayer Introduction to SQLAlchemy @ Postgres Open
Michael Bayer Introduction to SQLAlchemy @ Postgres OpenMichael Bayer Introduction to SQLAlchemy @ Postgres Open
Michael Bayer Introduction to SQLAlchemy @ Postgres OpenPostgresOpen
 
Python and EM CLI: The Enterprise Management Super Tools
Python and EM CLI: The Enterprise Management Super ToolsPython and EM CLI: The Enterprise Management Super Tools
Python and EM CLI: The Enterprise Management Super ToolsSeth Miller
 
Behold the Power of Python
Behold the Power of PythonBehold the Power of Python
Behold the Power of PythonSarah Dutkiewicz
 
What is Python? An overview of Python for science.
What is Python? An overview of Python for science.What is Python? An overview of Python for science.
What is Python? An overview of Python for science.Nicholas Pringle
 
Big data analysis in python @ PyCon.tw 2013
Big data analysis in python @ PyCon.tw 2013Big data analysis in python @ PyCon.tw 2013
Big data analysis in python @ PyCon.tw 2013Jimmy Lai
 
Programming with Python and PostgreSQL
Programming with Python and PostgreSQLProgramming with Python and PostgreSQL
Programming with Python and PostgreSQLPeter Eisentraut
 
Python in the database
Python in the databasePython in the database
Python in the databasepybcn
 
Python PPT
Python PPTPython PPT
Python PPTEdureka!
 
Learn 90% of Python in 90 Minutes
Learn 90% of Python in 90 MinutesLearn 90% of Python in 90 Minutes
Learn 90% of Python in 90 MinutesMatt Harrison
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to PythonNowell Strite
 

En vedette (11)

Michael Bayer Introduction to SQLAlchemy @ Postgres Open
Michael Bayer Introduction to SQLAlchemy @ Postgres OpenMichael Bayer Introduction to SQLAlchemy @ Postgres Open
Michael Bayer Introduction to SQLAlchemy @ Postgres Open
 
Python and EM CLI: The Enterprise Management Super Tools
Python and EM CLI: The Enterprise Management Super ToolsPython and EM CLI: The Enterprise Management Super Tools
Python and EM CLI: The Enterprise Management Super Tools
 
Behold the Power of Python
Behold the Power of PythonBehold the Power of Python
Behold the Power of Python
 
What is Python? An overview of Python for science.
What is Python? An overview of Python for science.What is Python? An overview of Python for science.
What is Python? An overview of Python for science.
 
Big data analysis in python @ PyCon.tw 2013
Big data analysis in python @ PyCon.tw 2013Big data analysis in python @ PyCon.tw 2013
Big data analysis in python @ PyCon.tw 2013
 
Programming with Python and PostgreSQL
Programming with Python and PostgreSQLProgramming with Python and PostgreSQL
Programming with Python and PostgreSQL
 
Python in the database
Python in the databasePython in the database
Python in the database
 
Python PPT
Python PPTPython PPT
Python PPT
 
Python Presentation
Python PresentationPython Presentation
Python Presentation
 
Learn 90% of Python in 90 Minutes
Learn 90% of Python in 90 MinutesLearn 90% of Python in 90 Minutes
Learn 90% of Python in 90 Minutes
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 

Similaire à Relational Database Access with Python

Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architectureJung Kim
 
Icinga 2010 at Nagios Workshop
Icinga 2010 at Nagios WorkshopIcinga 2010 at Nagios Workshop
Icinga 2010 at Nagios WorkshopIcinga
 
Introduction to cloudforecast
Introduction to cloudforecastIntroduction to cloudforecast
Introduction to cloudforecastMasahiro Nagano
 
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...Databricks
 
Monitoring as Code: Getting to Monitoring-Driven Development - DEV314 - re:In...
Monitoring as Code: Getting to Monitoring-Driven Development - DEV314 - re:In...Monitoring as Code: Getting to Monitoring-Driven Development - DEV314 - re:In...
Monitoring as Code: Getting to Monitoring-Driven Development - DEV314 - re:In...Amazon Web Services
 
Automating with NX-OS: Let's Get Started!
Automating with NX-OS: Let's Get Started!Automating with NX-OS: Let's Get Started!
Automating with NX-OS: Let's Get Started!Cisco DevNet
 
Finding target for hacking on internet is now easier
Finding target for hacking on internet is now easierFinding target for hacking on internet is now easier
Finding target for hacking on internet is now easierDavid Thomas
 
DBA だってもっと効率化したい!〜最近の自動化事情とOracle Database〜
DBA だってもっと効率化したい!〜最近の自動化事情とOracle Database〜DBA だってもっと効率化したい!〜最近の自動化事情とOracle Database〜
DBA だってもっと効率化したい!〜最近の自動化事情とOracle Database〜Michitoshi Yoshida
 
Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)DECK36
 
Developing with the Go client for Apache Kafka
Developing with the Go client for Apache KafkaDeveloping with the Go client for Apache Kafka
Developing with the Go client for Apache KafkaJoe Stein
 
Implementing a build manager in Ada
Implementing a build manager in AdaImplementing a build manager in Ada
Implementing a build manager in AdaStephane Carrez
 
Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用Qiangning Hong
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak PROIDEA
 

Similaire à Relational Database Access with Python (20)

Angular2 inter3
Angular2 inter3Angular2 inter3
Angular2 inter3
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architecture
 
Icinga 2010 at Nagios Workshop
Icinga 2010 at Nagios WorkshopIcinga 2010 at Nagios Workshop
Icinga 2010 at Nagios Workshop
 
Deep Learning for Computer Vision: Software Frameworks (UPC 2016)
Deep Learning for Computer Vision: Software Frameworks (UPC 2016)Deep Learning for Computer Vision: Software Frameworks (UPC 2016)
Deep Learning for Computer Vision: Software Frameworks (UPC 2016)
 
Introduction to cloudforecast
Introduction to cloudforecastIntroduction to cloudforecast
Introduction to cloudforecast
 
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...
 
De Java 8 a Java 17
De Java 8 a Java 17De Java 8 a Java 17
De Java 8 a Java 17
 
Monitoring as Code: Getting to Monitoring-Driven Development - DEV314 - re:In...
Monitoring as Code: Getting to Monitoring-Driven Development - DEV314 - re:In...Monitoring as Code: Getting to Monitoring-Driven Development - DEV314 - re:In...
Monitoring as Code: Getting to Monitoring-Driven Development - DEV314 - re:In...
 
Orms vs Micro-ORMs
Orms vs Micro-ORMsOrms vs Micro-ORMs
Orms vs Micro-ORMs
 
Automating with NX-OS: Let's Get Started!
Automating with NX-OS: Let's Get Started!Automating with NX-OS: Let's Get Started!
Automating with NX-OS: Let's Get Started!
 
Finding target for hacking on internet is now easier
Finding target for hacking on internet is now easierFinding target for hacking on internet is now easier
Finding target for hacking on internet is now easier
 
DBA だってもっと効率化したい!〜最近の自動化事情とOracle Database〜
DBA だってもっと効率化したい!〜最近の自動化事情とOracle Database〜DBA だってもっと効率化したい!〜最近の自動化事情とOracle Database〜
DBA だってもっと効率化したい!〜最近の自動化事情とOracle Database〜
 
Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)
 
Developing with the Go client for Apache Kafka
Developing with the Go client for Apache KafkaDeveloping with the Go client for Apache Kafka
Developing with the Go client for Apache Kafka
 
Implementing a build manager in Ada
Implementing a build manager in AdaImplementing a build manager in Ada
Implementing a build manager in Ada
 
ql.io at NodePDX
ql.io at NodePDXql.io at NodePDX
ql.io at NodePDX
 
Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用
 
React inter3
React inter3React inter3
React inter3
 
Pycon - Python for ethical hackers
Pycon - Python for ethical hackers Pycon - Python for ethical hackers
Pycon - Python for ethical hackers
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
 

Plus de Mark Rees

Porting a legacy app to python 3
Porting a legacy app to python 3Porting a legacy app to python 3
Porting a legacy app to python 3Mark Rees
 
Seeing with Python presented at PyCon AU 2014
Seeing with Python presented at PyCon AU 2014Seeing with Python presented at PyCon AU 2014
Seeing with Python presented at PyCon AU 2014Mark Rees
 
Seeing with Python - Pycon SG 2014
Seeing with Python - Pycon SG 2014Seeing with Python - Pycon SG 2014
Seeing with Python - Pycon SG 2014Mark Rees
 
Pypy is-it-ready-for-production-the-sequel
Pypy is-it-ready-for-production-the-sequelPypy is-it-ready-for-production-the-sequel
Pypy is-it-ready-for-production-the-sequelMark Rees
 
PyPy - is it ready for production
PyPy - is it ready for productionPyPy - is it ready for production
PyPy - is it ready for productionMark Rees
 
What do you mean it needs to be Java based? How jython saved the day.
What do you mean it needs to be Java based? How jython saved the day.What do you mean it needs to be Java based? How jython saved the day.
What do you mean it needs to be Java based? How jython saved the day.Mark Rees
 

Plus de Mark Rees (6)

Porting a legacy app to python 3
Porting a legacy app to python 3Porting a legacy app to python 3
Porting a legacy app to python 3
 
Seeing with Python presented at PyCon AU 2014
Seeing with Python presented at PyCon AU 2014Seeing with Python presented at PyCon AU 2014
Seeing with Python presented at PyCon AU 2014
 
Seeing with Python - Pycon SG 2014
Seeing with Python - Pycon SG 2014Seeing with Python - Pycon SG 2014
Seeing with Python - Pycon SG 2014
 
Pypy is-it-ready-for-production-the-sequel
Pypy is-it-ready-for-production-the-sequelPypy is-it-ready-for-production-the-sequel
Pypy is-it-ready-for-production-the-sequel
 
PyPy - is it ready for production
PyPy - is it ready for productionPyPy - is it ready for production
PyPy - is it ready for production
 
What do you mean it needs to be Java based? How jython saved the day.
What do you mean it needs to be Java based? How jython saved the day.What do you mean it needs to be Java based? How jython saved the day.
What do you mean it needs to be Java based? How jython saved the day.
 

Dernier

Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...amber724300
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfAarwolf Industries LLC
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialJoão Esperancinha
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 

Dernier (20)

Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdf
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorial
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 

Relational Database Access with Python

  • 1. Relational Database Access with Python Why you should be using SQLAlchemy Mark Rees CTO Century Software (M) Sdn. Bhd.
  • 2. Is This Your Current Relational Database Access Style? # Django ORM >>> from ip2country.models import Ip2Country >>> Ip2Country.objects.all() [<Ip2Country: Ip2Country object>, <Ip2Country: Ip2Country object>, '...(remaining elements truncated)...'] >>> myp = Ip2Country.objects.filter(assigned__year=2015) ... .filter(countrycode2=’MY') >>> myp[0].ipfrom 736425984.0
  • 3. Is This Your Current Relational Database Access Style? # SQLAlchemy ORM >>> from sqlalchemy import create_engine, extract >>> from sqlalchemy.orm import sessionmaker >>> from models import Ip2Country >>> engine = create_engine('postgresql://ip2country_rw:secret@localhost/i p2country') >>> Session = sessionmaker(bind=engine) >>> session = Session() >>> all_data = session.query(Ip2Country).all() >>> myp = session.query(Ip2Country). ... filter(extract('year',Ip2Country.assigned) == 2015). ... filter(Ip2Country.countrycode2 == ’MY') print(myp[0].ipfrom) 736425984.0
  • 4. SQL Relational Database Access SELECT * FROM ip2country; “id”,"ipfrom";"ipto";"registry";"assigned";"countrycode2";"countrycode3";"countryname" 1,1729522688;1729523711;"apnic";"2011-08-05";"CN";"CHN";"China" 2,1729523712;1729524735;"apnic";"2011-08-05";"CN";"CHN";"China” . . . SELECT * FROM ip2country WHERE date_part('year', assigned) = 2015 AND countrycode2 = ’MY'; “id”,"ipfrom";"ipto";"registry";"assigned";"countrycode2";"countrycode3";"countryname" 5217;736425984;736427007;"apnic";"2015-01-13 00:00:00";"MY";"MYS";"Malaysia” 5218;736427008;736428031;"apnic";"2015-01-13 00:00:00";"MY";"MYS";"Malaysia” . . . SELECT ipfrom FROM ip2country WHERE date_part('year', assigned) = 2015 AND countrycode2 = ’MY'; "ipfrom" 736425984 736427008 . . .
  • 5. Python + SQL == Python DB-API 2.0 • The Python standard for a consistent interface to relational databases is the Python DB-API (PEP 249) • The majority of Python database interfaces adhere to this standard
  • 7. Python DB-API Connection Object Access the database via the connection object • Use connect constructor to create a connection with database conn = psycopg2.connect(parameters…) • Create cursor via the connection cur = conn.cursor() • Transaction management (implicit begin) conn.commit() conn.rollback() • Close connection (will rollback current transaction) conn.close() • Check module capabilities by globals psycopg2.apilevel psycopg2.threadsafety psycopg2.paramstyle
  • 8. Python DB-API Cursor Object A cursor object is used to represent a database cursor, which is used to manage the context of fetch operations. • Cursors created from the same connection are not isolated cur = conn.cursor() cur2 = conn.cursor() • Cursor methods cur.execute(operation, parameters) cur.executemany(op,seq_of_parameters) cur.fetchone() cur.fetchmany([size=cursor.arraysize]) cur.fetchall() cur.close()
  • 9. Python DB-API Cursor Object • Optional cursor methods cur.scroll(value[,mode='relative']) cur.next() cur.callproc(procname[,parameters]) cur.__iter__() • Results of an operation cur.description cur.rowcount cur.lastrowid • DB adaptor specific “proprietary” cursor methods
  • 10. Python DB-API Parameter Styles Allows you to keep SQL separate from parameters Improves performance & security Warning Never, never, NEVER use Python string concatenation (+) or string parameters interpolation (%) to pass variables to a SQL query string. Not even at gunpoint. From http://initd.org/psycopg/docs/usage.html#query-parameters
  • 11. Python DB-API Parameter Styles Global paramstyle gives supported style for the adaptor qmark Question mark style WHERE countrycode2 = ? numeric Numeric positional style WHERE countrycode2 = :1 named Named style WHERE countrycode2 = :code format ANSI C printf format style WHERE countrycode2 = %s pyformat Python format style WHERE countrycode2 = %(name)s
  • 12. Python + SQL: INSERT import csv, datetime, psycopg2 conn = psycopg2.connect("dbname=ip2countrydb user=ip2country_rw password=secret") cur = conn.cursor() with open("IpToCountry.csv", "rt") as f: reader = csv.reader(f) try: for row in reader: if row[0][0] != "#": row[3] = datetime.datetime.utcfromtimestamp(float(row[3])) cur.execute("""INSERT INTO ip2country( ipfrom, ipto, registry, assigned, countrycode2, countrycode3, countryname) VALUES (%s, %s, %s, %s, %s, %s, %s)""", row) except (Exception) as error: print(error) conn.rollback() else: conn.commit() finally: cur.close() conn.close()
  • 13. Python + SQL: SELECT # Find ipv4 address ranges assigned to Malaysia import psycopg2, socket, struct def num_to_dotted_quad(n): """convert long int to dotted quad string http://code.activestate.com/recipes/66517/""" return socket.inet_ntoa(struct.pack('!L', n)) conn = psycopg2.connect("dbname=ip2countrydb user=ip2country_rw password=secret") cur = conn.cursor() cur.execute("""SELECT * FROM ip2country WHERE countrycode2 = 'MY' ORDER BY ipfrom""") for row in cur: print("%s - %s" % (num_to_dotted_quad(int(row[0])), num_to_dotted_quad(int(row[1]))))
  • 14. SQLite • sqlite3 • CPython 2.5 & 3 • DB-API 2.0 • Part of CPython distribution since 2.5
  • 15. PostgreSQL • psycopg • CPython 2 & 3 • DB-API 2.0, level 2 thread safe • Appears to be most popular • http://initd.org/psycopg/ • py-postgresql • CPython 3 • DB-API 2.0 • Written in Python with optional C optimizations • pg_python - console • http://python.projects.postgresql.org/
  • 16. PostgreSQL • PyGreSQL • CPython 2.5+ • Classic & DB-API 2.0 interfaces • http://www.pygresql.org/ • pyPgSQL • CPython 2 • Classic & DB-API 2.0 interfaces • http://pypgsql.sourceforge.net/ • Last release 2006
  • 17. PostgreSQL • pypq • CPython 2.7 & pypy 1.7+ • Uses ctypes • DB-API 2.0 interface • psycopg2-like extension API • https://bitbucket.org/descent/pypq • psycopg2cffi • CPython 2.6+ & pypy 2.0+ • Uses cffi • DB-API 2.0 interface • psycopg2 compat layer • https://github.com/chtd/psycopg2cffi
  • 18. MySQL • MySQL-python • CPython 2.3+ • DB-API 2.0 interface • http://sourceforge.net/projects/mysql- python/ • PyMySQL • CPython 2.4+ & 3 • Pure Python DB-API 2.0 interface • http://www.pymysql.org/ • MySQL-Connector • CPython 2.4+ & 3 • Pure Python DB-API 2.0 interface • https://launchpad.net/myconnpy
  • 19. Other “Enterprise” Databases • cx_Oracle • CPython 2 & 3 • DB-API 2.0 interface • http://cx-oracle.sourceforge.net/ • informixda • CPython 2 • DB-API 2.0 interface • http://informixdb.sourceforge.net/ • Last release 2007 • Ibm-db • CPython 2 • DB-API 2.0 for DB2 & Informix • http://code.google.com/p/ibm-db/
  • 20. ODBC • mxODBC • CPython 2.3+ • DB-API 2.0 interfaces • http://www.egenix.com/products/pytho n/mxODBC/doc • Commercial product • PyODBC • CPython 2 & 3 • DB-API 2.0 interfaces with extensions • https://github.com/mkleehammer/pyod bc • ODBC interfaces not limited to Windows thanks to iODBC and unixODBC
  • 21. Jython + SQL • zxJDBC • DB-API 2.0 Written in Java using JDBC API so can utilize JDBC drivers • Support for connection pools and JNDI lookup • Included with standard Jython installation http://www.jython.org/ • jyjdbc • DB-API 2.0 compliant • Written in Python/Jython so can utilize JDBC drivers • Decimal data type support • https://bitbucket.org/clach04/jyjdbc/
  • 22. IronPython + SQL • adodbapi • IronPython 2+ • Also works with CPython 2.3+ with pywin32 • http://adodbapi.sourceforge.net/
  • 23. Gerald, the half a schema import gerald s1 = gerald.PostgresSchema(’public', 'postgres://ip2country_rw:secret@localhost/ip2country') s2 = gerald.PostgresSchema(’public', 'postgres://ip2country_rw:secret@localhost/ip2countryv4') print s1.schema['ip2country'].compare(s2.schema['ip2country']) DIFF: Definition of assigned is different DIFF: Column countryname not in ip2country DIFF: Definition of registry is different DIFF: Column countrycode3 not in ip2country DIFF: Definition of countrycode2 is different • Database schema toolkit • via DB-API currently supports • PostgreSQL • MySQL • Oracle • http://halfcooked.com/code/gerald/
  • 24. SQLPython $ sqlpython --postgresql ip2country ip2country_rw Password: 0:ip2country_rw@ip2country> select * from ip2country where countrycode2='SG'; ... 1728830464.0 1728830719.0 apnic 2011-11-02 SG SGP Singapore 551 rows selected. 0:ip2country_rw@ip2country> select * from ip2country where countrycode2='SG'j [... {"ipfrom": 1728830464.0, "ipto": 1728830719.0, "registry": "apnic”,"assigned": "2011-11-02", "countrycode2": "SG", "countrycode3": "SGP", "countryname": "Singapore"}] • A command-line interface to relational databases • via DB-API currently supports • PostgreSQL • MySQL • Oracle • http://packages.python.org/sqlpython/
  • 25. SQLPython, batteries included 0:ip2country_rw@ip2country> select * from ip2country where countrycode2 =’MY’; ... 1728830464.0 1728830719.0 apnic 2011-11-02 MY MYS Malaysia 551 rows selected. 0:ip2country_rw@ip2country> py Python 2.6.6 (r266:84292, May 20 2011, 16:42:25) [GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2 py <command>: Executes a Python command. py: Enters interactive Python mode. End with `Ctrl-D` (Unix) / `Ctrl-Z` (Windows), `quit()`, 'exit()`. Past SELECT results are exposed as list `r`; most recent resultset is `r[-1]`. SQL bind, substitution variables are exposed as `binds`, `substs`. Run python code from external files with ``run("filename.py")`` >>> r[-1][-1] (1728830464.0, 1728830719.0, 'apnic', datetime.date(2011, 11, 2), ’MY', ’MYS', ’Malaysia') >>> import socket, struct >>> def num_to_dotted_quad(n): ... return socket.inet_ntoa(struct.pack('!L',n)) ... >>> num_to_dotted_quad(int(r[-1][-1].ipfrom)) '103.11.220.0'
  • 26. SpringPython – Database Templates # Find ipv4 address ranges assigned to Malaysia # using SpringPython DatabaseTemplate & DictionaryRowMapper from springpython.database.core import * from springpython.database.factory import * conn_factory = PgdbConnectionFactory( user="ip2country_rw", password="secret", host="localhost", database="ip2countrydb") dt = DatabaseTemplate(conn_factory) results = dt.query( "SELECT * FROM ip2country WHERE countrycode2=%s", (”MY",), DictionaryRowMapper()) for row in results: print("%s - %s" % (num_to_dotted_quad(int(row['ipfrom'])), num_to_dotted_quad(int(row['ipto']))))
  • 27. SQLAlchemy http://www.sqlalchemy.org/ First release in 2005 Now at version 1.0.8 What is it • Provides helpers, tools & components to assist with database access • Provides a consisdent and full featured façade over the Python DBAPI • Provides an optional object relational mapper(ORM) • Foundation for many Python third party libraries & tools • It doesn’t hide the database, you need understand SQL
  • 29. SQLAlchemy Core – The Engine from sqlalchemy import create_engine engine = create_engine('postgresql://ip2country_rw:secret@localhost/i p2countrydb') engine.execute(""" create table registry ( id serial primary key, name text ) """) engine.execute(""" insert into registry(name) values('apnic') """) engine.execute(""" insert into registry(name) values('aprn') ""”) engine.execute(""" insert into registry(name) values('lacnic') """)
  • 30. SQLAlchemy Core – SQL Expression Language from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData engine = create_engine('postgresql://ip2country_rw:secret@localhost/ip2countrydb', echo=True) metadata = MetaData() registry = Table('registry', metadata, Column('id', Integer, autoincrement=True, primary_key=True), Column('name', String(10))) metadata.create_all(engine) # create table if it doesn't exist # auto construct insert statement with binding parameters ins = registry.insert().values(name='dummy’) conn = engine.connect() # get database connection # insert multiple rows with explicit commit conn.execute(ins, [{'name': 'apnic'}, {'name': 'aprn'}, {'name': 'lacnic'}])
  • 31. SQLAlchemy Core – SQL Expression Language from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData from sqlalchemy.sql import select engine = create_engine('postgresql://ip2country_rw:secret@localhost/ip2countrydb', echo=True) metadata = MetaData() registry = Table('registry', metadata, Column('id', Integer, autoincrement=True, primary_key=True, Column('name', String(10))) # auto create select statement s = select([registry]) conn = engine.connect() result = conn.execute(s) for row in result: print(row)
  • 32. SQLAlchemy Core – SQL Expression Language from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData from sqlalchemy.sql import select engine = create_engine('postgresql://ip2country_rw:secret@localhost/ip2countrydb', echo=True) metadata = MetaData() registry = Table('registry', metadata, Column('id', Integer, autoincrement=True, primary_key=True, Column('name', String(10))) # auto create select statement s = select([registry]) conn = engine.connect() result = conn.execute(s) for row in result: print(row)
  • 33. SQLAlchemy ORM from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import create_engine, Table, Column, Integer, String Base = declarative_base() class Registry(Base): __tablename__ = 'registry' id = Column(Integer, autoincrement=True, primary_key=True) name = Column(String(10)) def __repr__(self): return "<Registry(%r, %r)>" % ( self.id, self.name ) engine = create_engine('postgresql://ip2country_rw:secret@localhost/ip2countrydb', echo=True) Base.metadata.create_all(engine) from sqlalchemy.orm import Session session = Session(bind=engine) apnic = session.query(Registry).filter_by(name='apnic').first() print(apnic)
  • 34. SQLAlchemy ORM . . . Base = declarative_base() class Registry(Base): __tablename__ = 'registry' id = Column(Integer, autoincrement=True, primary_key=True) name = Column(String(10)) def __repr__(self): return "<Registry(%r, %r)>" % ( self.id, self.name ) engine = create_engine('postgresql://ip2country_rw:secret@localhost/ip2countrydb', echo=True) Base.metadata.create_all(engine) from sqlalchemy.orm import Session session = Session(bind=engine) mynic = Registry(name='mynic') session.add(mynic)
  • 35. DB-API 2.0 PEP http://www.python.org/dev/peps/pep-0249/ Travis Spencer’s DB-API UML Diagram http://travisspencer.com/ Andrew Kuchling's introduction to the DB-API http://www.amk.ca/python/writing/DB-API.html Attributions
  • 36. Andy Todd’s OSDC paper http://halfcooked.com/presentations/osdc2006/p ython_databases.html Source of csv data used in examples from WebNet77 licensed under GPLv3 http://software77.net/geo-ip/ Attributions
  • 37. Mark Rees mark at censof dot com +Mark Rees @hexdump42 hex-dump.blogspot.com Contact Details

Notes de l'éditeur

  1. If you were at PyCon APAC 2012, the first part of this talk will a case of déjà vu if you attended my talk there.
  2. For some Python programmers, their only exposure to accessing relational data is via a object relational mapper (ORM). As powerful is the concept of mapping objects to data, sometimes it is much simpler to manipulate your relational data using SQL. This talk will be about using the DB-API, Python’s standard mechanism for accessing relational databases.
  3. Or maybe you prefer sqlalchemy to abstract away the database. Both the Django ORM and SQLAlchemy need a lower level API to access databases. So the first part of this talk will be about using the DB-API, Python’s standard mechanism for accessing relational databases.
  4. SQL (Structured Query Language) is a DSL and we can achieve the same results as the previous two slides. This what DBA’s program in. 
  5. This diagram no longer seems to exist on Travis’s site
  6. Always use parameter binding. Why? * you normally get better performance from some database engines due to to SQL query caching * reduce the chance of SQL injection
  7. Always use parameter binding. Why? * you normally get better performance from some database engines due to to SQL query caching * reduce the chance of SQL injection
  8. Gerald is a general purpose database schema toolkit written in Python. It can be used for cataloguing, managing and deploying database schemas. It is designed to allow you to easily identify the differences between databases.
  9. SQLPython is a command-line interface to relational databases written in Python. It was created as an alternative to Oracle’s SQL\*Plus, and can likewise be used instead of postgres’ psql or mysql’s mysql text clients. In addition, it offers several extra features inspired by other command-line clients: Neatened output, smart prompt, tab completion, history, scripting, output to file, paste buffer & os command, unix like commands – ls cat grep, data dictionary exploration. Another feature is special output formats. By replacing the ; that terminates a SELECT statement with a backslash-character sequence, you can get output in a number of useful formats like xml, json, csv etc
  10. One of the most powerful features is the py command. The py command allows the user to execute Python commands, either one-at-a-time (with py {command}) or in an interactive environment (beginning with a bare py statement, and continuing until Ctrl-D, quit(), or exit() is entered). A history of result sets from each query is exposed to the python session as the list r; the most recent result set is r[-1]. Each row can be references as a tuple, or as an object with an attribute for each column.
  11. Spring Python takes the concepts of the Spring Framework and Spring Security, and brings them to the world of Python. It isn't a simple line-by-line port of the code. Instead, it takes some powerful ideas that were discovered in the realm of Java, and pragmatically applies them in the world of Python. One of these paradigms is a Portable Service Abstraction called DatabaseTemplate. * It is portable because it uses Python's standardized API, not tying us to any database vendor. Instead, in our example, we injected in an instance of Sqlite3ConnectionFactory * It provides the useful service of easily accessing information stored in a relational database, but letting us focus on the query, not the plumbing code * It offers a nice abstraction over Python's low level database API with reduced code noise. This allows us to avoid the cost and risk of writing code to manage cursors and exception handling DatabaseTemplate handles exceptions by catching and holding them, then properly closing the cursor. It then raises it wrapped inside a Spring Python DataAccessException. This way, database resources are properly disposed of without losing the exception stack trace. The Database Template can be used in isolation from the SpringPython framework.
  12. Core Engine – a registry which provides connectivity to a particular database server Dialect – interprets generic SQL and database commands to match a specific DBAPI & database backend Connection Pool – a collection of database connections in memory for fast re-use SQL Expression Language – Allows SQL statements to be written using Python expressions Schema/Types – Uses objects to represent tables, columns and data types ORM Allows construction of Python objects which can be mapped to relational database tables Transparently persists objects into their corresponding database tables using the unit of work pattern Provides a query system which loads objects and attributes using SQL generated from mappings Built of top of the Core, uses core to generate SQL and talk to DB
  13. Not much different from using the DBAPI directly
  14. But using the SQL Expression Language it is more pythonic
  15. You can do the same for selects
  16. You can do the same for selects
  17. You use a session to use the unit of work pattern
  18. The session caches the add and doesn’t do the insert until the session is committed.