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

  1. Importera sqlite-modulen med

    >>> import sqlite3
    
  2. 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:')
    
  3. När du har en Connection kan du skapa ett Cursor och kalla dess execute() -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

  1. 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 eller EXCLUSIVE .

  1. cursor

    Markörobjektet används för att köra SQL-kommandon och frågor.

  1. commit()

    Åtar den aktuella transaktionen.

  1. rollback()

    Återgår alla ändringar som gjorts sedan föregående uppmaning commit()

  1. close()

    Stänger databasanslutningen. Det kallar inte commit() automatiskt. Om close() kallas utan att först ringa commit() (förutsatt att du inte är i autocommit-läge) kommer alla ändringar att gå förlorade.

  1. total_changes

    Ett attribut som loggar det totala antalet rader som har ändrats, raderats eller infogats sedan databasen öppnades.

  2. execute , executemany och executescript

    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

  1. 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

  1. 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 ).

  1. 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]),
    
  2. 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 eller bytes .

    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 ett SELECT uttalande, kan du antingen behandla markören som en iterator, ringa markörens fetchone() -metod för att hämta en enda matchande rad eller ringa fetchall() 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)
    
  3. 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)
    
  4. 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)]
    
  5. 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:

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

Referens

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)


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow