pythonmysqlsqlite3
1、MySQLdb
# 前置條件
sudo apt-get install python-dev libmysqlclient-dev # Ubuntu
sudo yum install python-devel mysql-devel # Red Hat / CentOS
# 安裝
pip install MySQL-python
Windows 直接通過下載 exe 文件安裝
#!/usr/bin/python
import MySQLdb
db = MySQLdb.connect(
host = "localhost", # 主機名
user = "root", # 用戶名
passwd = "pythontab.com", # 密碼
db = "testdb") # 資料庫名稱
# 查詢前,必須先獲取游標
cur = db.cursor()
# 執行的都是原生SQL語句
cur.execute("SELECT * FROM mytable")
for row in cur.fetchall():
print(row[0])
db.close()
2、mysqlclient
# Windows安裝
pip install some-package.whl
# linux 前置條件
sudo apt-get install python3-dev # debian / Ubuntu
sudo yum install python3-devel # Red Hat / CentOS
brew install mysql-connector-c # macOS (Homebrew)
pip install mysqlclient
3、PyMySQL
pip install PyMySQL
# 為了兼容mysqldb,只需要加入
pymysql.install_as_MySQLdb()
import pymysql
conn = pymysql.connect(host = 飗.0.0.1', user = 'root', passwd = "pythontab.com", db = 'testdb')
cur = conn.cursor()
cur.execute("SELECT Host,User FROM user")
for r in cur:
print(r)
cur.close()
conn.close()
4、peewee
pip install peewee
import peewee
from peewee import *
db = MySQLDatabase('testdb', user = 'root', passwd = 'pythontab.com')
class Book(peewee.Model):
author = peewee.CharField()
title = peewee.TextField()
class Meta:
database = db
Book.create_table()
book = Book(author = "pythontab", title = 'pythontab is good website')
book.save()
for book in Book.filter(author = "pythontab"):
print(book.title)
5、SQLAlchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy_declarative import Address, Base, Person
class Address(Base):
__tablename__ = 'address'
id = Column(Integer, primary_key = True)
street_name = Column(String(250))
engine = create_engine('sqlite:///sqlalchemy_example.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind = engine)
session = DBSession()
# Insert a Person in the person table
new_person = Person(name = 'new person')
session.add(new_person)
session.commit()
❷ 有沒有人嘗試python3+django1.6+mysql connector 1.1.3
改掉系統默認的sqlite3資料庫,
# Database
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
'ENGINE': 'django.db.backends.mysql',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'NAME':'djangoDB',
'USER':'root',
'PASSWORD':'123456',
'port':'3306',
}
}
然後啟動報錯,
ImportError: No mole named 'MySQLdb'
據說要裝MySQL-python
可是MySQL-python一直無法安裝成功。
又報錯ImportError: No mole named 'ConfigParser'
因為python3中叫做configparser,是小寫。
好吧,聽說不用MySQL-python可以用pymsql代替,然後就趕緊下載pip install pymysql
然後再啟動,還是不行啊,還是ImportError: No mole named 'MySQLdb'
這里說下MySQL-python吧。
MySQL-python的解釋看官方說法
MySQLdb is an interface to the popular MySQL database server for Python. The design goals are:
Compliance with Python database API version 2.0 [PEP-0249]
Thread-safety
Thread-friendliness (threads will not block each other)
MySQL-3.23 through 5.5 and Python-2.4 through 2.7 are currently supported. Python-3.0 will be supported in a future release. PyPy is supported.
說白了就是連接mysql的python介面,有了他就可以用python來操作資料庫了。類似java的JDBC那一套東西把。
❸ ubuntu學習python安裝哪個mysql
在用Django時,資料庫如果選擇MySQL,那麼需要安裝MySQL-Python,以下是簡明安裝教程:
1. 到下載安裝包,截至筆者發稿,MySQL-python的版本為:MySQL-python-1.2.4b4.tar.gz。
2. 解壓,筆者解壓到了~/temp目錄下:
[plain] view plain
$ tar -zxvf MySQL-python-1.2.4b4.tar.gz -C ~/temp/
3. 在終端裡面執行以下命令:
[plain] view plain
$ mysql_config
如果提示未找到命令,則安裝終端提示你的包,如下:
則安裝:
[plain] view plain
$ sudo apt-get install libmysqlclient-dev
4. 我們打開MySQL-python-1.2.4b4目錄(步驟2中解壓得到的目錄)中的site.cfg文件,看到有這樣的說明:
意思就是說,如果mysql_config腳本不在PATH中,我們就解注釋下面的代碼,並修改這行代碼後面的路徑,以告知mysql_config腳本的位置;如果mysql_config這個腳本在PATH中,就不要改了,否則會出現一些匪夷所思的現象。遵旨!
5. 為了知曉我們到底用不用改site.cfg,再次嘗試在終端執行:
[plain] view plain
$ mysql_config
如果出現以下結果:
則說明mysql_config腳本在PATH中(或者說在MySQL-python過程中我它能找到mysql_config腳本),那麼我們就不用修改site.cfg;
如果未出現,則就按著步驟4所述修改site.cfg,可以在終端執行如下命令,來尋找mysql_config這個腳本的路徑:
[plain] view plain
$ find / -name mysql_config
得到mysql_config的路徑(應該很快,find命令據推測應該會先在PATH變數中的路徑尋找,出來第一條結果後適時終止執行即可),修改site.cfg。
6. 若MySQL是通過apt-get安裝的,那麼我們還要安裝python-dev包,來提供安裝過程中必須的Python.h這個頭文件:
[plain] view plain
$ sudo apt-get install python-dev
7. 准備工作終於做完了!現在趕緊去解壓得到的文件夾MySQL-python-1.2.4b4下,運行:
[plain] view plain
$ sudo python setup.py build
$ sudo python setup.py install
8. 測試一下,在python命令行中執行:
[plain] view plain
import MySQLdb
如果沒出現錯誤,說明我們成功安裝了MySQL-python。
附:Django中驗證某一項目成功連接MySQL的方法:
樣例settings.DATABASES:
[python] view plain
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'db_name', # Or path to database file if using sqlite3.
'USER': 'your_MySQL_uname', # Not used with sqlite3.
'PASSWORD': 'your_pwd', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
在項目目錄通過以下命令啟動Python Shell:
[plain] view plain
$ python manage.py shell
註:以上命令是以正確配置啟動Shell的一種方法。
接著在Shell中輸入下列命令測試MySQL連接:
[python] view plain
>>>from django.db import connection
>>>c = connection.cursor()
如果沒有顯示什麼錯誤信息,那麼你的資料庫配置是正確的。
❹ Python MySQL executemany的使用
個人理解:
execute中要使用對等格式 如 name(char), age(int),此時語句為: cur.execute("insert into db.table(name,age) values(%s,%d)" % (v[name], v[age]) ,v[name]為字元,v[age]為int
executemany中不需要強制格式,同上表語句為:
values=[("zhan",23),("li",33)]
executemany("insert into db.tables(name,age) values(%s,%s)",values)
具體原因我也不清楚,只能說是走過的坑吧,executemany一般只用%s即可,用其它的可能會報錯。插入後的值是正常的(貌似是自動匹配列屬性?),有大俠知道的也望指教
❺ 在python3下怎樣用flask-sqlalchemy對mysql資料庫操作
這個問題經常難道新手一下,因為大部分教程里(包括經典的《Flask Web開發》一書),告訴了我們如何使用flask-sqlalchemy操作sqlite,但在生產環境(線上網站)上,我們肯定是使用MySQL或其他,而大部分的教程里,又告訴我們flask-sqlalchemy使用MySQL的方式是:
mysql://username:password@server/db
結果我們照葫蘆畫瓢的來一下,發現壓根不行,寫好的網站一跟資料庫沾邊就報錯。
Python和MySQL是「兩個國家的人」,他們互不相通,因而需要一個中間代理,讓雙方互通有無,跟翻譯一樣(這比喻不準確,但足夠你明白意思就行)。翻譯又有很多選擇,不同的翻譯各有特色。
題主解決問題選擇的翻譯是「flask-mysqldb」,其背後的主子是「MySQL-python」。恩,說到這里你應該知道,「flask-xxx」這樣的包都是對背後主子進行了適合Flask封裝的插件,跟包子皮一樣,裡面的餡才是重點,「flask-mysqldb」的餡是「MySQL-python」。
而我要推薦的是另一個翻譯:PyMySQL,這玩意的好處是可以做非同步(「MySQL-python」也可以,個人口味罷了),簡而言之,網站訪問量大了就需要考慮非同步,現在別管這是啥子。這玩意的安裝方式是:
pip install PyMySQL
之後,資料庫連接由:
mysql://username:password@server/db
改為
mysql+pymysql://username:password@server/db
就可以了。
❻ 怎麼實現python寫網頁後台實現與資料庫交互
1、批處理腳本中,要想與用戶實行交互,需要用到命令set 配合/p參數一起使用。
❼ 後端編程Python3-資料庫編程
對大多數軟體開發者而言,術語資料庫通常是指RDBMS(關系資料庫管理系統), 這些系統使用表格(類似於電子表格的網格),其中行表示記錄,列表示記錄的欄位。表格及其中存放的數據是使用SQL (結構化査詢語言)編寫的語句來創建並操縱的。Python提供了用於操縱SQL資料庫的API(應用程序介面),通常與作為標準的SQLite 3資料庫一起發布。
另一種資料庫是DBM (資料庫管理器),其中存放任意數量的鍵-值項。Python 的標准庫提供了幾種DBM的介面,包括某些特定於UNIX平台的。DBM的工作方式 與Python中的字典類似,區別在於DBM通常存放於磁碟上而不是內存中,並且其鍵與值總是bytes對象,並可能受到長度限制。本章第一節中講解的shelve模塊提供了方便的DBM介面,允許我們使用字元串作為鍵,使用任意(picklable)對象作為值。
如果可用的 DBM 與 SQLite 資料庫不夠充分,Python Package Index, pypi.python.org/pypi中提供了大量資料庫相關的包,包括bsddb DBM ("Berkeley DB"),對象-關系映射器,比如SQLAlchemy (www.sqlalchemy.org),以及流行的客戶端/伺服器數據的介面,比如 DB2、Informix、Ingres、MySQL、ODBC 以及 PostgreSQL。
本章中,我們將實現某程序的兩個版本,該程序用於維護一個DVD列表,並追蹤每個DVD的標題、發行年份、時間長度以及發行者。該程序的第一版使用DBM (通過shelve模塊)存放其數據,第二版則使用SQLite資料庫。兩個程序都可以載入與保存簡單的XML格式,這使得從某個程序導出DVD數據並將其導入到其他程序成為可能。與DBM版相比,基於SQL的程序提供了更多一些的功能,並且其數據設計也稍干凈一些。
12.1 DBM資料庫
shelve模塊為DBM提供了一個wrapper,藉助於此,我們在與DBM交互時,可以將其看做一個字典,這里是假定我們只使用字元串鍵與picklable值,實際處理時, shelve模塊會將鍵與值轉換為bytes對象(或者反過來)。
由於shelve模塊使用的是底層的DBM,因此,如果其他計算機上沒有同樣的DBM,那麼在某台計算機上保存的DBM文件在其他機器上無法讀取是可能的。為解決這一問題,常見的解決方案是對那些必須在機器之間可傳輸的文件提供XML導入與導出功能,這也是我們在本節的DVD程序dvds-dbm.py中所做的。
對鍵,我們使用DVD的標題;對值,則使用元組,其中存放發行者、發行年份以及時間。藉助於shelve模塊,我們不需要進行任何數據轉換,並可以把DBM對象當做一個字典進行處理。
程序在結構上類似於我們前面看到的那種菜單驅動型的程序,因此,這里主要展示的是與DBM程序設計相關的那部分。下面給出的是程序main()函數中的一部分, 忽略了其中菜單處理的部分代碼。
db = None
try:
db = shelve.open(filename, protocol=pickle.HIGHEST_PROTOCOL)
finally:
if db is not None:
db.dose()
這里我們已打開(如果不存在就創建)指定的DBM文件,以便於對其進行讀寫操作。每一項的值使用指定的pickle協議保存為一個pickle,現有的項可以被讀取, 即便是使用更底層的協議保存的,因為Python可以計算出用於讀取pickle的正確協議。最後,DBM被關閉——其作用是清除DBM的內部緩存,並確保磁碟文件可以反映出已作的任何改變,此外,文件也需要關閉。
該程序提供了用於添加、編輯、列出、移除、導入、導出DVD數據的相應選項。除添加外,我們將忽略大部分用戶介面代碼,同樣是因為已經在其他上下文中進行了展示。
def add_dvd(db):
title = Console.get_string("Title", "title")
if not title:
return
director = Console.get_string("Director", "director")
if not director:
return
year = Console.get_integer("Year", "year",minimum=1896,
maximum=datetime,date.today().year)
ration = Console.get_integer("Duration (minutes)", "minutes「, minimum=0, maximum=60*48)
db[title] = (director, year, ration)
db.sync()
像程序菜單調用的所有函數一樣,這一函數也以DBM對象(db)作為其唯一參數。該函數的大部分工作都是獲取DVD的詳細資料,在倒數第二行,我們將鍵-值項存儲在DBM文件中,DVD的標題作為鍵,發行者、年份以及時間(由shelve模塊pickled在一起)作為值。
為與Python通常的一致性同步,DBM提供了與字典一樣的API,因此,除了 shelve.open() 函數(前面已展示)與shelve.Shelf.sync()方法(該方法用於清除shelve的內部緩存,並對磁碟上文件的數據與所做的改變進行同步——這里就是添加一個新項),我們不需要學習任何新語法。
def edit_dvd(db):
old_title = find_dvd(db, "edit")
if old_title is None:
return
title = Console.get.string("Title", "title", old_title)
if not title:
return
director, year, ration = db[old_title]
...
db[title]= (director, year, ration)
if title != old_title:
del db[old_title]
db.sync()
為對某個DVD進行編輯,用戶必須首先選擇要操作的DVD,也就是獲取DVD 的標題,因為標題用作鍵,值則用於存放其他相關數據。由於必要的功能在其他場合 (比如移除DVD)也需要使用,因此我們將其實現在一個單獨的find_dvd()函數中,稍後將査看該函數。如果找到了該DVD,我們就獲取用戶所做的改變,並使用現有值作為默認值,以便提高交互的速度。(對於這一函數,我們忽略了大部分用戶介面代碼, 因為其與添加DVD時幾乎是相同的。)最後,我們保存數據,就像添加時所做的一樣。如果標題未作改變,就重寫相關聯的值;如果標題已改變,就創建一個新的鍵-值對, 並且需要刪除原始項。
def find_dvd(db, message):
message = "(Start of) title to " + message
while True:
matches =[]
start = Console.get_string(message, "title")
if not start:
return None
for title in db:
if title.lower().startswith(start.lower()):
matches.append(title)
if len(matches) == 0:
print("There are no dvds starting with", start)
continue
elif len(matches) == 1:
return matches[0]
elif len(matches) > DISPLAY_LIMIT:
print("Too many dvds start with {0}; try entering more of the title".format(start)
continue
else:
matches = sorted(matches, key=str.lower)
for i, match in enumerate(matches):
print("{0}: {1}".format(i+1, match))
which = Console.get_integer("Number (or 0 to cancel)",
"number", minimum=1, maximum=len(matches))
return matches[which - 1] if which != 0 else None
為盡可能快而容易地發現某個DVD,我們需要用戶只輸入其標題的一個或頭幾個字元。在具備了標題的起始字元後,我們在DBM中迭代並創建一個匹配列表。如果只有一個匹配項,就返回該項;如果有幾個匹配項(但少於DISPLAY_LIMIT, 一個在程序中其他地方設置的整數),就以大小寫不敏感的順序展示所有這些匹配項,並為每一項設置一個編號,以便用戶可以只輸入編號就可以選擇某個標題。(Console.get_integer()函數可以接受0,即便最小值大於0,以便0可以用作一個刪除值。通過使用參數allow_zero=False, 可以禁止這種行為。我們不能使用Enter鍵,也就是說,沒有什麼意味著取消,因為什麼也不輸入意味著接受默認值。)
def list_dvds(db):
start =」"
if len(db)> DISPLAY.LIMIT:
start = Console.get_string(「List those starting with [Enter=all]」, "start」)
print()
for title in sorted(db, key=str.lower):
if not start or title.Iower().startswith(start.lower()):
director, year, ration = db[title]
print("{title} ({year}) {ration} minute{0}, by "
"{director}".format(Util.s(ration),**locals()))
列出所有DVD (或者那些標題以某個子字元串引導)就是對DBM的所有項進行迭代。
Util.s()函數就是簡單的s = lambda x: "" if x == 1 else "s",因此,如果時間長度不是1分鍾,就返回"s"。
def remove_dvd(db):
title = find_dvd(db, "remove")
if title is None:
return
ans = Console.get_bool("Remove {0}?".format(title), "no")
if ans:
del db[title]
db.sync()
要移除一個DVD,首先需要找到用戶要移除的DVD,並請求確認,獲取後從DBM中刪除該項即可。
到這里,我們展示了如何使用shelve模塊打開(或創建)一個DBM文件,以及如何向其中添加項、編輯項、對其項進行迭代以及移除某個項。
遺憾的是,在我們的數據設計中存在一個瑕疵。發行者名稱是重復的,這很容易導致不一致性,比如,發行者Danny DeVito可能被輸入為"Danny De Vito",用於 一個電影;也可以輸入為「Danny deVito",用於另一個。為解決這一問題,可以使用兩個DBM文件,主DVD文件使用標題鍵與(年份,時間長度,發行者ID)值; 發行者文件使用發行者ID (整數)鍵與發行者名稱值。下一節展示的SQL資料庫 版程序將避免這一瑕疵,這是通過使用兩個表格實現的,一個用於DVD,另一個用於發行者。
12.2 SQL資料庫
大多數流行的SQL資料庫的介面在第三方模塊中是可用的,Python帶有sqlite3 模塊(以及SQLite 3資料庫),因此,在Python中,可以直接開始資料庫程序設計。SQLite是一個輕量級的SQL資料庫,缺少很多諸如PostgreSQL這種資料庫的功能, 但非常便於構造原型系統,並且在很多情況下也是夠用的。
為使後台資料庫之間的切換盡可能容易,PEP 249 (Python Database API Specification v2.0)提供了稱為DB-API 2.0的API規范。資料庫介面應該遵循這一規范,比如sqlite3模塊就遵循這一規范,但不是所有第三方模塊都遵循。API規范中指定了兩種主要的對象,即連接對象與游標對象。表12-1與表12-2中分別列出了這兩種對象必須支持的API。在sqlite3模塊中,除DB-API 2.0規范必需的之外,其連接對象與游標對象都提供了很多附加的屬性與方法。
DVD程序的SQL版本為dvds.sql.py,該程序將發行者與DVD數據分開存儲,以 避免重復,並提供一個新菜單,以供用戶列出發行者。該程序使用的兩個表格在圖12-1
def connect(filename):
create= not os.path.exists(filename)
db = sqlite3.connect(filename)
if create:
cursor = db.cursor()
cursor.execute("CREATE TABLE directors ("
"id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, "
"name TEXT UNIQUE NOT NULL)")
cursor.execute("CREATE TABLE dvds ("
"id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, "
"title TEXT NOT NULL, "
"year INTEGER NOT NULL,"
"ration INTEGER NOT NULL, "
"director_id INTEGER NOT NULL, 」
"FOREIGN KEY (director_id) REFERENCES directors)")
db.commit()
return db
sqlite3.connect()函數會返回一個資料庫對象,並打開其指定的資料庫文件。如果該文件不存在,就創建一個空的資料庫文件。鑒於此,在調用sqlite3.connect()之前,我們要注意資料庫是否是准備從頭開始創建,如果是,就必須創建該程序要使用的表格。所有査詢都是通過一個資料庫游標完成的,可以從資料庫對象的cursor()方法獲取。
注意,兩個表格都是使用一個ID欄位創建的,ID欄位有一個AUTOINCREMENT 約束——這意味著SQLite會自動為ID欄位賦予唯一性的數值,因此,在插入新記錄時,我們可以將這些欄位留給SQLite處理。
SQLite支持有限的數據類型——實際上就是布爾型、數值型與字元串——但使用數據'『適配器」可以對其進行擴展,或者是擴展到預定義的數據類型(比如那些用於日期與datetimes的類型),或者是用於表示任意數據類型的自定義類型。DVD程序並不需要這一功能,如果需要,sqlite3模塊的文檔提供了很多詳細解釋。我們使用的外部鍵語法可能與用於其他資料庫的語法不同,並且在任何情況下,只是記錄我們的意圖,因為SQLite不像很多其他資料庫那樣需要強制關系完整性,sqlite3另一點與眾不同的地方在於其默認行為是支持隱式的事務處理,因此,沒有提供顯式的「開始事務」 方法。
def add_dvd(db):
title = Console.get_string("Title", "title")
if not title:
return
director = Console.get_string("Director", "director")
if not director:
return
year = Console.get_integer("Year", "year」, minimum=1896,
maximum=datetime.date.today().year)
ration = Console.get_integer("Duration (minutes)", "minutes",
minimum=0,maximum=60*48)
director_id = get_and_set_director(db, director)
cursor = db.cursor()
cursor.execute("INSERT INTO dvds 」
"(title, year, ration, director_id)"
"VALUES (?, ?, ?, ?)",
(title, year, ration, director_id))
db.commit()
這一函數的開始代碼與dvds-dbm.py程序中的對應函數一樣,但在完成數據的收集後,與原來的函數有很大的差別。用戶輸入的發行者可能在也可能不在directors表格中,因此,我們有一個get_and_set_director()函數,在資料庫中尚無某個發行者時, 該函數就將其插入到其中,無論哪種情況都返回就緒的發行者ID,以便在需要的時候插入到dvds表。在所有數據都可用後,我們執行一條SQL INSERT語句。我們不需要指定記錄ID,因為SQLite會自動為我們提供。
在査詢中,我們使用問號(?)作為佔位符,每個?都由包含SQL語句的字元串後面的序列中的值替代。命名的佔位符也可以使用,後面在編輯記錄時我們將看到。盡管避免使用佔位符(而只是簡單地使用嵌入到其中的數據來格式化SQL字元串)也是可能的,我們建議總是使用佔位符,並將數據項正確編碼與轉義的工作留給資料庫模塊來完成。使用佔位符的另一個好處是可以提高安全性,因為這可以防止任意的SQL 被惡意地插入到一個査詢中。
def get_and_set_director(db, director):
director_id = get_director_id(db, director)
if directorjd is not None:
return director_id
cursor = db.cursor()
cursor.execute("lNSERT INTO directors (name) VALUES (?)」,(director,))
db.commit()
return get_director_id(db, director)
這一函數返回給定發行者的ID,並在必要的時候插入新的發行者記錄。如果某個記錄被插入,我們首先嘗試使用get_director_id()函數取回其ID。
def get_director_id(db, director):
cursor = db.cursor()
cursor.execute("SELECT id FROM directors WHERE name=?",(director,))
fields = cursor.fetchone()
return fields[0] if fields is not None else None
get_director_id()函數返回給定發行者的ID,如果資料庫中沒有指定的發行者,就返回None。我們使用fetchone()方法,因為或者有一個匹配的記錄,或者沒有。(我們知道,不會有重復的發行者,因為directors表格的名稱欄位有一個UNIQUE約束,在任何情況下,在添加一個新的發行者之前,我們總是先檢査其是否存在。)這種取回方法總是返回一個欄位序列(如果沒有更多的記錄,就返回None)。即便如此,這里我們只是請求返回一個單獨的欄位。
def edit_dvd(db):
title, identity = find_dvd(db, "edit")
if title is None:
return
title = Console.get_string("Title","title", title)
if not title:
return
cursor = db.cursor()
cursor.execute("SELECT dvds.year, dvds.ration, directors.name"
「FROM dvds, directors "
"WHERE dvds.director_id = directors.id AND "
"dvds.id=:id", dict(id=identity))
year, ration, director = cursor.fetchone()
director = Console.get_string("Director", "director", director)
if not director:
return
year = Console,get_integer("Year","year", year, 1896,datetime.date.today().year)
ration = Console.get_integer("Duration (minutes)", "minutes",
ration, minimum=0, maximum=60*48)
director_id = get_and_set_director(db, director)
cursor.execute("UPDATE dvds SET title=:title, year=:year,"
"ration=:ration, director_id=:directorjd "
"WHERE id=:identity", locals())
db.commit()
要編輯DVD記錄,我們必須首先找到用戶需要操縱的記錄。如果找到了某個記錄,我們就給用戶修改其標題的機會,之後取回該記錄的其他欄位,以便將現有值作為默認值,將用戶的輸入工作最小化,用戶只需要按Enter鍵就可以接受默認值。這里,我們使用了命名的佔位符(形式為:name),並且必須使用映射來提供相應的值。對SELECT語句,我們使用一個新創建的字典;對UPDATE語句,我們使用的是由 locals()返回的字典。
我們可以同時為這兩個語句都使用新字典,這種情況下,對UPDATE語句,我們可以傳遞 dict(title=title, year=year, ration=ration, director_id=director_id, id=identity)),而非 locals()。
在具備所有欄位並且用戶已經輸入了需要做的改變之後,我們取回相應的發行者ID (如果必要就插入新的發行者記錄),之後使用新數據對資料庫進行更新。我們採用了一種簡化的方法,對記錄的所有欄位進行更新,而不僅僅是那些做了修改的欄位。
在使用DBM文件時,DVD標題被用作鍵,因此,如果標題進行了修改,我們就需要創建一個新的鍵-值項,並刪除原始項。不過,這里每個DVD記錄都有一個唯一性的ID,該ID是記錄初次插入時創建的,因此,我們只需要改變任何其他欄位的值, 而不需要其他操作。
def find_dvd(db, message):
message = "(Start of) title to " + message
cursor = db.cursor()
while True: .
start = Console.get_stnng(message, "title")
if not start:
return (None, None)
cursor.execute("SELECT title, id FROM dvds "
"WHERE title LIKE ? ORDER BY title」,
(start +"%",))
records = cursor.fetchall()
if len(records) == 0:
print("There are no dvds starting with", start)
continue
elif len(records) == 1:
return records[0]
elif len(records) > DISPLAY_LIMIT:
print("Too many dvds ({0}) start with {1}; try entering "
"more of the title".format(len(records),start))
continue
else:
for i, record in enumerate(records):
print("{0}:{1}".format(i + 1, record[0]))
which = Console.get_integer("Number (or 0 to cancel)",
"number", minimum=1, maximum=len(records))
return records[which -1] if which != 0 else (None, None)
這一函數的功能與dvdsdbm.py程序中的find_dvd()函數相同,並返回一個二元組 (DVD標題,DVD ID)或(None, None),具體依賴於是否找到了某個記錄。這里並不需要在所有數據上進行迭代,而是使用SQL通配符(%),因此只取回相關的記錄。
由於我們希望匹配的記錄數較小,因此我們一次性將其都取回到序列的序列中。如果有不止一個匹配的記錄,但數量上又少到可以顯示,我們就列印記錄,並將每條記錄附帶一個數字編號,以便用戶可以選擇需要的記錄,其方式與在dvds-dbm.py程序中所做的類似:
def list_dvds(db):
cursor = db.cursor()
sql = ("SELECT dvds.title, dvds.year, dvds.ration, "
"directors.name FROM dvds, directors "
"WHERE dvds.director_id = directors.id")
start = None
if dvd_count(db) > DISPLAY_LIMIT:
start = Console.get_string("List those starting with [Enter=all]", "start")
sql += " AND dvds.title LIKE ?"
sql += 」 ORDER BY dvds.title"
print()
if start is None:
cursor.execute(sql)
else:
cursor.execute(sql, (start +"%",))
for record in cursor:
print("{0[0]} ({0[1]}) {0[2]} minutes, by {0[3]}".format(record))
要列出每個DVD的詳細資料,我們執行一個SELECT査詢。該査詢連接兩個表,如果記錄(由dvd_count()函數返回)數量超過了顯示限制值,就將第2個元素添加到WHERE 分支,之後執行該査詢,並在結果上進行迭代。每個記錄都是一個序列,其欄位是與 SELECT査詢相匹配的。
def dvd_count(db):
cursor = db.cursor()
cursor.execute("SELECT COUNT(*) FROM dvds")
return cursor.fetchone()[0]
我們將這幾行代碼放置在一個單獨的函數中,因為我們在幾個不同的函數中都需要使用這幾行代碼。
我們忽略了 list_directors()函數的代碼,因為該函數在結構上與list_dvds()函數非常類似,只不過更簡單一些,因為本函數只列出一個欄位(name)。
def remove_dvd(db):
title, identity = find_dvd(db, "remove")
if title is None:
return
ans = Console.get_bool("Remove {0}?".format(title), "no")
if ans:
cursor = db.cursor()
cursor.execute("DELETE FROM dvds WHERE id=?", (identity,))
db.commit()
在用戶需要刪除一個記錄時,將調用本函數,並且本函數與dvds-dbm.py程序中 相應的函數是非常類似的。
到此,我們完全查閱了 dvds-sql.py程序,並且了解了如何創建資料庫表格、選取 記錄、在選定的記錄上進行迭代以及插入、更新與刪除記錄。使用execute()方法,我們可以執行底層資料庫所支持的任意SQL語句。
SQLite提供了比我們這里使用的多得多的功能,包括自動提交模式(以及任意其他類型的事務控制),以及創建可以在SQL查詢內執行的函數的能力。提供一個工廠函數並用於控制對每個取回的記錄返回什麼(比如,一個字典或自定義類型,而不是欄位序列)也是可能的。此外,通過傳遞「:memory:」作為文件名,創建內存中的SQLite 資料庫也是可能的。
以上內容部分摘自視頻課程05後端編程Python22 資料庫編程,更多實操示例請參照視頻講解。跟著張員外講編程,學習更輕松,不花錢還能學習真本領。
❽ 怎麼用python連接mysql資料庫
在 Python 語言環境下我們這樣連接資料庫。
In [1]: from mysql import connector
In [2]: cnx = connector.connect(host="172.16.192.100",port=3306,user="appuser",password="xxxxxx")
但是連接資料庫的背後發生了什麼呢?
答案
當我們通過驅動程序(mysql-connector-python,pymysql)連接 MySQL 服務端的時候,就是把連接參數傳遞給驅動程序,驅動程序再根據參數會發起到 MySQL 服務端的 TCP 連接。當 TCP 連接建立之後驅動程序與服務端之間會按特定的格式和次序交換數據包,數據包的格式和發送次序由MySQL 協議規定。MySQL 協議:https://dev.mysql.com/doc/internals/en/client-server-protocol.html整個連接的過程中 MySQL 服務端與驅動程序之間,按如下的次序發送了這些包。
MySQL 服務端向客戶端發送一個握手包,包里記錄了 MySQL-Server 的版本,默認的授權插件,密碼鹽值(auth-data)。
2. MySQL 客戶端發出 ssl 連接請求包(如果有必要的話)。
3. MySQL 客戶端發出握手包的響應包,這個包時記錄了用戶名,密碼加密後的串,客戶端屬性,等等其它信息。
4. MySQL 服務端發出響應包,這個包里記錄了登錄是否成功,如果沒有成功也會給出錯誤信息。
❾ 對python來說mysql和postgresql哪個好
python操作資料庫PostgreSQL
1.簡述
python可以操作多種資料庫,諸如SQLite、MySql、PostgreSQL等,這里不對所有的資料庫操作方法進行贅述,只針對目前
項目中用到的PostgreSQL做一下簡單介紹,主要包括python操作資料庫插件的選擇、安裝、簡單使用方法、測試連接資料庫成功。
2.資料庫操作插件的選擇
PostgreSQL至少有三個python介面程序可以實現訪問,包括PsyCopg、PyPgSQL、PyGreSQL(PoPy已經整合在PyGreSQL中),三個介面程序各有利弊,需要根據實踐選擇最適合項目的方式。
推薦使用PsyCopg,對python開發框架的兼容性都很好,本文中我們只討論這個插件。
3.PsyCopg的下載
官網下載psycopg2-2.5.1.tar.gz:http://initd.org/psycopg/
本文使用windows系統開發,未使用官網版本,選擇psycopg2-2.4.2.win-amd64-py2.7-pg9.0.4-release.exe版,地址:http://vdisk.weibo.com/s/Cd8pPaw56Ozys
4.PsyCopg的安裝
直接exe,根據提示安裝即可.
5.PsyCopg的使用
py文件代碼:
__author__ = 'qiongmiaoer'
import psycopg2
# 資料庫連接參數
conn = psycopg2.connect(database="platoon", user="postgres", password="postgres", host="192.168.10.80", port="5432")
cur = conn.cursor()
cur.execute("CREATE TABLE test(id serial PRIMARY KEY, num integer,data varchar);")
# insert one item
cur.execute("INSERT INTO test(num, data)VALUES(%s, %s)", (1, 'aaa'))
cur.execute("INSERT INTO test(num, data)VALUES(%s, %s)", (2, 'bbb'))
cur.execute("INSERT INTO test(num, data)VALUES(%s, %s)", (3, 'ccc'))
cur.execute("SELECT * FROM test;")
rows = cur.fetchall() # all rows in table
print(rows)
for i in rows:
print(i)
conn.commit()
cur.close()
conn.close()
可參考psycopg官方文檔,介紹postgresql的使用
http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries
6. 輸出結果
"C:\Program Files (x86)\Python275\python.exe" E:/PycharmProjects/psycopgPyCharm/xiaoyu/temp.py
[(1, 1, 'aaa'), (2, 2, 'bbb'), (3, 3, 'ccc')]
(1, 1, 'aaa')
(2, 2, 'bbb')
(3, 3, 'ccc')
Process finished with exit code 0
7.分析
在插件psyCopg安裝後,在python命令下import
psycopg2,即可使用psycopg2中的方法對資料庫,根據測試結果的輸出可以看到我們成功地連接到了資料庫,創建了名為test的table,
添加了三條數據,並成功讀取和輸出數據,最後將查詢到的數據輸出print出來。
ps:
項目環境
windows8
python2.7.5
pyCharm2.7.3(開發環境)
psycopg2-2.4.2(插件)