Python Language
Databasåtkomst
Sök…
Anmärkningar
Python kan hantera många olika typer av databaser. För var och en av dessa typer finns ett annat API. Så uppmuntra likhet mellan dessa olika API: er, PEP 249 har införts.
Detta API har definierats för att uppmuntra likhet mellan Python-modulerna som används för att komma åt databaser. Genom att göra detta hoppas vi uppnå en konsistens som leder till mer lättförståelige moduler, kod som i allmänhet är mer portabel över databaser och en bredare räckvidd för databasanslutning från Python. PEP-249
Åtkomst till MySQL-databas med MySQLdb
Det första du behöver göra är att skapa en anslutning till databasen med anslutningsmetoden. Efter det behöver du en markör som fungerar med den anslutningen.
Använd markörens körningsmetod för att interagera med databasen, och gör då och då ändringarna med hjälp av kopplingsmetoden för anslutningsobjektet.
När allt är klart, glöm inte att stänga markören och anslutningen.
Här är en Dbconnect-klass med allt du behöver.
import MySQLdb
class Dbconnect(object):
def __init__(self):
self.dbconection = MySQLdb.connect(host='host_example',
port=int('port_example'),
user='user_example',
passwd='pass_example',
db='schema_example')
self.dbcursor = self.dbconection.cursor()
def commit_db(self):
self.dbconection.commit()
def close_db(self):
self.dbcursor.close()
self.dbconection.close()
Att interagera med databasen är enkelt. När du har skapat objektet använder du bara exekveringsmetoden.
db = Dbconnect()
db.dbcursor.execute('SELECT * FROM %s' % 'table_example')
Om du vill ringa en lagrad procedur använder du följande syntax. Observera att parameterlistan är valfri.
db = Dbconnect()
db.callproc('stored_procedure_name', [parameters] )
När frågan är klar kan du få åtkomst till resultaten på flera sätt. Markörobjektet är en generator som kan hämta alla resultat eller slingas.
results = db.dbcursor.fetchall()
for individual_row in results:
first_field = individual_row[0]
Om du vill ha en slinga med direkt generator:
for individual_row in db.dbcursor:
first_field = individual_row[0]
Om du vill göra ändringar i databasen:
db.commit_db()
Om du vill stänga markören och anslutningen:
db.close_db()
SQLite
SQLite är en lätt, diskbaserad databas. Eftersom den inte kräver en separat databasserver används den ofta för prototyper eller för små applikationer som ofta används av en enda användare eller av en användare vid en viss tidpunkt.
import sqlite3
conn = sqlite3.connect("users.db")
c = conn.cursor()
c.execute("CREATE TABLE user (name text, age integer)")
c.execute("INSERT INTO user VALUES ('User A', 42)")
c.execute("INSERT INTO user VALUES ('User B', 43)")
conn.commit()
c.execute("SELECT * FROM user")
print(c.fetchall())
conn.close()
Koden ovan ansluter till databasen som är lagrad i filen med namnet users.db
och skapar filen först om den inte redan finns. Du kan interagera med databasen via SQL-satser.
Resultatet av detta exempel bör vara:
[(u'User A', 42), (u'User B', 43)]
SQLite Syntax: En djupgående analys
Komma igång
Importera sqlite-modulen med
>>> import sqlite3
För att använda modulen måste du först skapa ett anslutningsobjekt som representerar databasen. Här lagras data i filen exempel.db:
>>> conn = sqlite3.connect('users.db')
Alternativt kan du också ange specialnamnet
:memory:
att skapa en tillfällig databas i RAM, enligt följande:>>> conn = sqlite3.connect(':memory:')
När du har en
Connection
kan du skapa ettCursor
och kalla dessexecute()
-metod för att utföra SQL-kommandon:c = conn.cursor() # Create table c.execute('''CREATE TABLE stocks (date text, trans text, symbol text, qty real, price real)''') # Insert a row of data c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") # Save (commit) the changes conn.commit() # We can also close the connection if we are done with it. # Just be sure any changes have been committed or they will be lost. conn.close()
Viktiga attribut och funktioner för Connection
isolation_level
Det är ett attribut som används för att få eller ställa in den aktuella isoleringsnivån. Inget för autocommit-läge eller för
DEFERRED
,IMMEDIATE
ellerEXCLUSIVE
.
cursor
Markörobjektet används för att köra SQL-kommandon och frågor.
commit()
Åtar den aktuella transaktionen.
rollback()
Återgår alla ändringar som gjorts sedan föregående uppmaning
commit()
close()
Stänger databasanslutningen. Det kallar inte
commit()
automatiskt. Omclose()
kallas utan att först ringacommit()
(förutsatt att du inte är i autocommit-läge) kommer alla ändringar att gå förlorade.
total_changes
Ett attribut som loggar det totala antalet rader som har ändrats, raderats eller infogats sedan databasen öppnades.
execute
,executemany
ochexecutescript
Dessa funktioner fungerar på samma sätt som markörobjektet. Det här är en genväg, eftersom att anropa dessa funktioner genom anslutningsobjektet resulterar i skapandet av ett mellanliggande markörobjekt och kallar motsvarande metod för markörobjektet
row_factory
Du kan ändra detta attribut till en konverterbar som accepterar markören och den ursprungliga raden som en tupel och returnerar den verkliga resultatraden.
def dict_factory(cursor, row): d = {} for i, col in enumerate(cursor.description): d[col[0]] = row[i] return d conn = sqlite3.connect(":memory:") conn.row_factory = dict_factory
Viktiga funktioner för Cursor
execute(sql[, parameters])
Kör ett enda SQL-uttalande. SQL-uttalandet kan parametriseras (dvs. platshållare istället för SQL-bokstäver). SQLite3-modulen stöder två typer av platshållare: frågetecken
?
("Qmark-stil") och namngivna platshållare:name
("namngivna stil").import sqlite3 conn = sqlite3.connect(":memory:") cur = conn.cursor() cur.execute("create table people (name, age)") who = "Sophia" age = 37 # This is the qmark style: cur.execute("insert into people values (?, ?)", (who, age)) # And this is the named style: cur.execute("select * from people where name=:who and age=:age", {"who": who, "age": age}) # the keys correspond to the placeholders in SQL print(cur.fetchone())
Akta dig: använd inte
%s
för att infoga strängar i SQL-kommandon eftersom det kan göra ditt program sårbart för en SQL-injektionsattack (se SQL Injection ).
executemany(sql, seq_of_parameters)
Utför ett SQL-kommando mot alla parametersekvenser eller mappningar som finns i sekvensen sql. SQLite3-modulen tillåter också att använda en iterator som ger parametrar istället för en sekvens.
L = [(1, 'abcd', 'dfj', 300), # A list of tuples to be inserted into the database (2, 'cfgd', 'dyfj', 400), (3, 'sdd', 'dfjh', 300.50)] conn = sqlite3.connect("test1.db") conn.execute("create table if not exists book (id int, name text, author text, price real)") conn.executemany("insert into book values (?, ?, ?, ?)", L) for row in conn.execute("select * from book"): print(row)
Du kan också skicka iteratorobjekt som en parameter till exekverande, och funktionen itereras över varje tupel av värden som iteratorn returnerar. Iteratorn måste returnera ett antal värden.
import sqlite3 class IterChars: def __init__(self): self.count = ord('a') def __iter__(self): return self def __next__(self): # (use next(self) for Python 2) if self.count > ord('z'): raise StopIteration self.count += 1 return (chr(self.count - 1),) conn = sqlite3.connect("abc.db") cur = conn.cursor() cur.execute("create table characters(c)") theIter = IterChars() cur.executemany("insert into characters(c) values (?)", theIter) rows = cur.execute("select c from characters") for row in rows: print(row[0]),
executescript(sql_script)
Detta är en icke-standardiserad bekvämhetsmetod för att köra flera SQL-satser samtidigt. Den ger ut ett
COMMIT
uttalande först och kör sedan SQL-skriptet som det får som en parameter.sql_script
kan vara ett exempel påstr
ellerbytes
.import sqlite3 conn = sqlite3.connect(":memory:") cur = conn.cursor() cur.executescript(""" create table person( firstname, lastname, age ); create table book( title, author, published ); insert into book(title, author, published) values ( 'Dirk Gently''s Holistic Detective Agency', 'Douglas Adams', 1987 ); """)
Nästa uppsättning funktioner används i samband med
SELECT
uttalanden i SQL. För att hämta data efter att ha kört ettSELECT
uttalande, kan du antingen behandla markören som en iterator, ringa markörensfetchone()
-metod för att hämta en enda matchande rad eller ringafetchall()
att få en lista över matchande rader.Exempel på iteratorform:
import sqlite3 stocks = [('2006-01-05', 'BUY', 'RHAT', 100, 35.14), ('2006-03-28', 'BUY', 'IBM', 1000, 45.0), ('2006-04-06', 'SELL', 'IBM', 500, 53.0), ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)] conn = sqlite3.connect(":memory:") conn.execute("create table stocks (date text, buysell text, symb text, amount int, price real)") conn.executemany("insert into stocks values (?, ?, ?, ?, ?)", stocks) cur = conn.cursor() for row in cur.execute('SELECT * FROM stocks ORDER BY price'): print(row) # Output: # ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) # ('2006-03-28', 'BUY', 'IBM', 1000, 45.0) # ('2006-04-06', 'SELL', 'IBM', 500, 53.0) # ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)
fetchone()
Hämtar nästa rad i en frågeställningsuppsättning, returnerar en enda sekvens eller Ingen när det inte finns fler data tillgängliga.
cur.execute('SELECT * FROM stocks ORDER BY price') i = cur.fetchone() while(i): print(i) i = cur.fetchone() # Output: # ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) # ('2006-03-28', 'BUY', 'IBM', 1000, 45.0) # ('2006-04-06', 'SELL', 'IBM', 500, 53.0) # ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)
fetchmany(size=cursor.arraysize)
Hämtar nästa uppsättning rader i ett frågeställning (anges efter storlek) och returnerar en lista. Om storlek utelämnas returnerar fetchmany en enda rad. En tom lista returneras när det inte finns fler rader tillgängliga.
cur.execute('SELECT * FROM stocks ORDER BY price') print(cur.fetchmany(2)) # Output: # [('2006-01-05', 'BUY', 'RHAT', 100, 35.14), ('2006-03-28', 'BUY', 'IBM', 1000, 45.0)]
fetchall()
Hämtar alla (återstående) rader i ett sökresultat och returnerar en lista.
cur.execute('SELECT * FROM stocks ORDER BY price') print(cur.fetchall()) # Output: # [('2006-01-05', 'BUY', 'RHAT', 100, 35.14), ('2006-03-28', 'BUY', 'IBM', 1000, 45.0), ('2006-04-06', 'SELL', 'IBM', 500, 53.0), ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)]
SQLite och Python-datatyper
SQLite stöder naturligtvis följande typer: NULL, INTEGER, REAL, TEXT, BLOB.
Så här konverteras datatyperna när du flyttar från SQL till Python eller vice versa.
None <-> NULL
int <-> INTEGER/INT
float <-> REAL/FLOAT
str <-> TEXT/VARCHAR(n)
bytes <-> BLOB
PostgreSQL-databasåtkomst med psycopg2
psycopg2 är den mest populära PostgreSQL-databasadaptern som är både lätt och effektiv. Det är den nuvarande implementeringen av PostgreSQL-adaptern.
Dess huvudfunktioner är den fullständiga implementeringen av Python DB API 2.0-specifikationen och trådens säkerhet (flera trådar kan dela samma anslutning)
Upprätta en anslutning till databasen och skapa en tabell
import psycopg2
# Establish a connection to the database.
# Replace parameter values with database credentials.
conn = psycopg2.connect(database="testpython",
user="postgres",
host="localhost",
password="abc123",
port="5432")
# Create a cursor. The cursor allows you to execute database queries.
cur = conn.cursor()
# Create a table. Initialise the table name, the column names and data type.
cur.execute("""CREATE TABLE FRUITS (
id INT ,
fruit_name TEXT,
color TEXT,
price REAL
)""")
conn.commit()
conn.close()
Infoga data i tabellen:
# After creating the table as shown above, insert values into it.
cur.execute("""INSERT INTO FRUITS (id, fruit_name, color, price)
VALUES (1, 'Apples', 'green', 1.00)""")
cur.execute("""INSERT INTO FRUITS (id, fruit_name, color, price)
VALUES (1, 'Bananas', 'yellow', 0.80)""")
Hämtar tabelldata:
# Set up a query and execute it
cur.execute("""SELECT id, fruit_name, color, price
FROM fruits""")
# Fetch the data
rows = cur.fetchall()
# Do stuff with the data
for row in rows:
print "ID = {} ".format(row[0])
print "FRUIT NAME = {}".format(row[1])
print("COLOR = {}".format(row[2]))
print("PRICE = {}".format(row[3]))
Utgången från ovanstående skulle vara:
ID = 1
NAME = Apples
COLOR = green
PRICE = 1.0
ID = 2
NAME = Bananas
COLOR = yellow
PRICE = 0.8
Och så, där går du, du vet nu hälften av allt du behöver veta om psycopg2 ! :)
Oracle-databas
Förutsättningar:
- cx_Oracle-paket - Se här för alla versioner
- Oracle instant client - För Windows x64 , Linux x64
Uppstart:
Installera paketet cx_Oracle som:
sudo rpm -i <YOUR_PACKAGE_FILENAME>
Extrahera Oracle-omedelbar klient och ställ in miljövariabler som:
ORACLE_HOME=<PATH_TO_INSTANTCLIENT>
PATH=$ORACLE_HOME:$PATH
LD_LIBRARY_PATH=<PATH_TO_INSTANTCLIENT>:$LD_LIBRARY_PATH
Skapa en anslutning:
import cx_Oracle
class OraExec(object):
_db_connection = None
_db_cur = None
def __init__(self):
self._db_connection =
cx_Oracle.connect('<USERNAME>/<PASSWORD>@<HOSTNAME>:<PORT>/<SERVICE_NAME>')
self._db_cur = self._db_connection.cursor()
Hämta databasversion:
ver = con.version.split(".")
print ver
Provutgång: ['12', '1', '0', '2', '0']
Kör fråga: VÄLJ
_db_cur.execute("select * from employees order by emp_id")
for result in _db_cur:
print result
Output kommer att finnas i Python-tuples:
(10, 'SYSADMIN', 'IT-INFRA', 7)
(23, "HR ASSOCIATE", "HUMAN Resources", 6)
Kör fråga: INSERT
_db_cur.execute("insert into employees(emp_id, title, dept, grade)
values (31, 'MTS', 'ENGINEERING', 7)
_db_connection.commit()
När du utför infoga / uppdatera / radera operationer i en Oracle-databas är ändringarna endast tillgängliga inom din session tills commit
utfärdas. När de uppdaterade uppgifterna är engagerade i databasen är de sedan tillgängliga för andra användare och sessioner.
Kör fråga: INSERT med Bind-variabler
Bindvariabler gör att du kan köra uttalanden på nytt med nya värden, utan omkostnaderna för att analysera påståendet igen. Bindvariabler förbättrar återanvändbarhet för kod och kan minska risken för SQL-injektionsattacker.
rows = [ (1, "First" ),
(2, "Second" ),
(3, "Third" ) ]
_db_cur.bindarraysize = 3
_db_cur.setinputsizes(int, 10)
_db_cur.executemany("insert into mytab(id, data) values (:1, :2)", rows)
_db_connection.commit()
Stäng anslutning:
_db_connection.close()
Metoden stäng () stänger anslutningen. Alla anslutningar som inte uttryckligen stängs släpps automatiskt när skriptet avslutas.
Förbindelse
Skapa en anslutning
Enligt PEP 249 bör anslutningen till en databas upprättas med en connect()
-konstruktör, som returnerar ett Connection
objekt. Argumenten för denna konstruktör är databasberoende. Se databasspecifika ämnen för relevanta argument.
import MyDBAPI
con = MyDBAPI.connect(*database_dependent_args)
Detta anslutningsobjekt har fyra metoder:
1: stäng
con.close()
Stänger anslutningen direkt. Observera att anslutningen stängs automatiskt om metoden Connection.__del___
anropas. Eventuella väntande transaktioner kommer implicit att rullas tillbaka.
2: begå
con.commit()
Åtar alla väntande transaktioner till databasen.
3: rollback
con.rollback()
Återgår till början av alla väntande transaktioner. Med andra ord: detta avbryter alla transaktioner som inte är engagerade i databasen.
4: markör
cur = con.cursor()
Returnerar ett Cursor
. Detta används för att göra transaktioner i databasen.
Med hjälp av sqlalchemy
Så här använder du sqlalchemy för databas:
from sqlalchemy import create_engine
from sqlalchemy.engine.url import URL
url = URL(drivername='mysql',
username='user',
password='passwd',
host='host',
database='db')
engine = create_engine(url) # sqlalchemy engine
Nu kan denna motor användas: t.ex. med pandor för att hämta dataframe direkt från mysql
import pandas as pd
con = engine.connect()
dataframe = pd.read_sql(sql=query, con=con)