㈠ 如何在django中使用多個資料庫
使用多個資料庫
New in Django 1.2: Please, see the release notes
大多數其他文檔都假設使用單一資料庫,本文主要討論如何在 Django 中使用多個資料庫。 使用多個資料庫,要增加一些步驟。
定義你的資料庫
使用多資料庫的第一步是通過 DATABASES 設置要使用的資料庫服務。這個 設置用於映射資料庫別名和特定的聯結設置字典,這是 Django 定義資料庫一貫的手法。 字典內部的設置參見 DATABASES 文檔。
資料庫可以使用任何別名,但是 default 有特殊意義。當沒有選擇其他資料庫時, Django 總是使用別名為 default 的資料庫。因此,如果你沒有定義一個名為 default 的資料庫時,你應當小心了,在使用資料庫前要指定你想用的資料庫。
以下是一個定義兩個資料庫的 settings.py 代碼片斷。定義了一個預設的 Postgresql 資料庫和一個名為 users 的 MySQL 資料庫:
DATABASES = { 'default': { 'NAME': 'app_data', 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'USER': 'postgres_user', 'PASSWORD': 's3krit' }, 'users': { 'NAME': 'user_data', 'ENGINE': 'django.db.backends.mysql', 'USER': 'mysql_user', 'PASSWORD': 'priv4te' } }
如果你嘗試訪問 DATABASES 設置中沒有定義的資料庫, Django 會拋出一個 django.db.utils.ConnectionDoesNotExist異常。
同步你的資料庫
syncdb 管理命令一次只操作一個資料庫。預設情況下,它操作 default 資料庫。但是加上 --database 參數,你可以讓 syncdb 同步不同的 資料庫。所頌空以要同步我們例子中的所有資料庫的所有模型可以使用如下命令:
$ ./manage.py syncdb
$ ./manage.py syncdb --database=users
如果你不是同步所有的程序到同一個資料庫中,你可定義一個 資料庫路由 來為指定的模型實施特定的控制 策略。
如果你要精細地控制同步,那麼還有一種方式是修改 sqlall 的輸出,手工在 資料庫中執行命令,命令如下:
$ ./manage.py sqlall sales | ./manage.py dbshell
使用其他管理命令
其他操作資料庫的 django-admin.py 命令與 syncdb 類似,他們一次只 操作一個資料庫,使用 --database 來控制使用哪個資料庫。
自動資料庫路由
使用多資料庫最簡單的方法是設置一個數據啟鄭庫路由方案。預設的路由方案確保對象 「緊貼」其原本的資料庫(例如:一個對象從哪個資料庫取得,就保存回哪個資料庫)。 預設的路由方案還確保如果一個資料庫沒有指定,所有的查詢都會作用於 預設 數據 庫。
你不必為啟動預設路由方案作任何事,因為它是「開箱即用」的。但是,如果你要執行 一些更有趣的資料庫分配行為的話,你可以定義並安裝你自己的資料庫路由。
資料庫路由
一個資料庫路由是一個類,這個類最多有四個方法:
db_for_read(model, **hints)
建議 model 對象寫操作時使用的資料庫。
如果一個資料庫操作可以提供對選擇資料庫有用的附加信息,那麼可以通過 hints 字典提供。詳見 下文 。
如果沒有建議則返回 None 。
db_for_write(model, **hints)
建議 model 對象讀操作時使用的資料庫。
如果一悄櫻頌個資料庫操作可以提供對選擇資料庫有用的附加信息,那麼可以通過 hints 字典提供。詳見 下文 。
如果沒有建議則返回 None 。
allow_relation(obj1, obj2, **hints)
當 obj1 和 obj2 之間允許有關系時返回 True ,不允許時返回 False ,或者沒有 意見時返回 None 。這是一個純粹的驗證操作,用於外鍵和多對多操作中,兩個對象 的關系是否被允許。
allow_syncdb(db, model)
決定 model 是否可以和 db 為別名的資料庫同步。如果可以返回 True , 如果不可以返回 False ,或者沒有意見時返回 None 。這個方法用於決定一個給定 資料庫的模型是否可用。
一個路由不必提供 所有 這些方法,可以省略其中一個或多個。如果其中一個方法被 省略了,那麼 Django 會在執行相關檢查時跳過相應路由。
提示參數
資料庫路由接收的「提示」參數可用於決定哪個資料庫應當接收一個給定的請求。
目前,唯一可以提供的提示參數是 實例 ,即一個與讀寫操作相關的對象的實例。 可以是一個已保存的對象的實例,也可以是一個多對多關系中添加的實例。在某些情況下, 也可能沒有對象的實例可以提供。路由會檢查提示實例是否存在,並相應地決定是否改變 路由行為。
使用路由
資料庫路由使用 DATABASE_ROUTERS 設置來安裝。這個設置定義一個類名稱 列表,每個類定義一個用於主路由 (django.db.router) 的路由。
主路由用於 Django 分配資料庫操作。當一個查詢想要知道使用哪個資料庫時,會提供 一個模型和一個提示(如果有的話),並調用主路由。
Django 就會按次序嘗試每個路由,
直到找到合適的路由建議。如果找不到路由建議就會嘗試實例提示的當前的 _state.db 。如果沒有提供路由提示,或者實例沒有當前資料庫狀態,那麼
主路由會 分配 預設 資料庫。
一個例子
僅用於示例目的!
這個例子僅用於展示路由如何改變資料庫的使用。本例有意忽略了一些復雜的東西以 便於更好的展示路由是如何工作的。
如果任何一個 myapp 中的模型包含與 另一個 資料庫中模型的關系時,本例 是無效的。參見 跨資料庫關系一節中介紹 的 Django 引用完整性問題。
本例的主/從配置也是有缺陷的:它沒有處理復制延時(比如因為把寫操作傳遞給從 資料庫耗費時間而產生的查詢不一致),也沒有考慮與資料庫使用策略的交互作用。
那麼,這個例子有什麼用呢?本例僅用於演示一個 myapp 存在於 other 資料庫, 所有其他模型之間是主/從關系,且存在於 master 、 slave1 和 slave2 資料庫。本例使用了兩個路由:
class MyAppRouter(object): """ 一個控制 myapp 應用中模型的 所有資料庫操作的路由 """ def db_for_read(self, model, **hints): "myapp 應用中模型的操作指向 'other'" if model._meta.app_label == 'myapp': return 'other' return None def db_for_write(self, model, **hints): "myapp 應用中模型的操作指向 'other'" if model._meta.app_label == 'myapp': return 'other' return None def allow_relation(self, obj1, obj2, **hints): " 如果包含 myapp 應用中的模型則允許所有關系 " if obj1._meta.app_label == 'myapp' or obj2._meta.app_label == 'myapp': return True return None def allow_syncdb(self, db, model): " 確保 myapp 應用只存在於 'other' 資料庫 " if db == 'other': return model._meta.app_label == 'myapp' elif model._meta.app_label == 'myapp': return False return None class MasterSlaveRouter(object): """ 一個設置簡單主/從定義 的路由 """ def db_for_read(self, model, **hints): " 所有讀操作指向一個隨機的從資料庫 " return random.choice(['slave1','slave2']) def db_for_write(self, model, **hints): " 所有寫操作指向主資料庫 " return 'master' def allow_relation(self, obj1, obj2, **hints): " 允許資料庫池中的兩個對象間的任何關系 " db_list = ('master','slave1','slave2') if obj1._state.db in db_list and obj2._state.db in db_list: return True return None def allow_syncdb(self, db, model): " 顯示地放置所有資料庫中的模型 " return True
然後在你的設置文件增加如下內容(把 path.to. 替換為你定義路由的模型的路徑 ):
DATABASE_ROUTERS = ['path.to.MyAppRouter', 'path.to.MasterSlaveRouter']
這個設置中,路由的順序是很重要的,因為查詢時是按這個設置中的順序依次查詢的。上 例中, MyAppRouter 先於MasterSlaveRouter ,因此, myapp 中的模型就 優先於其他模型。如果 DATABASE_ROUTERS 設置中兩個路由的順序變換了, 那麼 MasterSlaveRouter.allow_syncdb() 會優先執行。因為 MasterSlaveRouter 是 包羅萬象的,這樣就會導致所有模型可以使用所有資料庫。
設置好之後讓我們來運行一些代碼:
>>> # 從 'credentials' 資料庫獲得數據 >>> fred = User.objects.get(username='fred') >>> fred.first_name = 'Frederick' >>> # 保存到 'credentials' 資料庫 >>> fred.save() >>> # 隨機從從資料庫獲得數據 >>> dna = Person.objects.get(name='Douglas Adams') >>> # 新對象創建時還沒有分配資料庫 >>> mh = Book(title='Mostly Harmless') >>> # 這個賦值會向路由發出請求,並把 mh 的資料庫設置為與 author 對象同樣的 >>> # 資料庫 >>> mh.author = dna >>> # 這會強制 'mh' 實例使用主資料庫... >>> mh.save() >>> # ... 但如果我們重新獲取對象,就會從從資料庫中獲取 >>> mh = Book.objects.get(title='Mostly Harmless')
手動選擇資料庫
Django 也提供一個可以讓你通過代碼完全控制資料庫使用的 API 。手動定義資料庫分配 優先於路由。
為一個 查詢集 手動選擇一個資料庫
你可以在 查詢集 「鏈」中的任何點為 查詢集 選擇資料庫。我們通過在 查詢集 上調用 using() 來得到使用指定資料庫的另一個 查詢集 。
using() 使用一個參數:你想要運行查詢的資料庫的別名。例如:
>>> # 這會運行在「預設」資料庫上。 >>> Author.objects.all() >>> # 這同樣會運行在「預設」資料庫上。 >>> Author.objects.using('default').all() >>> # 這會運行在「 other 」資料庫上。 >>> Author.objects.using('other').all()
為 save() 選擇一個資料庫
在使用 Model.save() 時加上 using 關鍵字可以指定保存到哪個資料庫。
例如,要把一個對象保存到 legacy_users 資料庫應該這樣做:
>>> my_object.save(using='legacy_users')
如果你不定義 using ,那麼 save() 方法會根據路由分配把數據保存到預設 資料庫中。
把一個對象從一個資料庫移動到另一個資料庫
當你已經在一個資料庫中保存了一個對象後,你可能會使用 save(using=...) 把這個 對象移動到另一個資料庫中。但是,如果你沒有使用恰當的方法,那麼可能會出現意想不 到的後果。
假設有如下的例子:
>>> p = Person(name='Fred') >>> p.save(using='first') # (第一句) >>> p.save(using='second') # (第二名)
在第一名中,一個新的 Person 對象被保存到 first 資料庫中。這時, p 還沒有一個主鍵,因此 Django 執行了一個INSERT SQL 語句。這樣就會創建一個 主鍵,並將這個主鍵分配給 p 。
在第二句中,因為 p 已經有了一個主鍵,所以 Django 在保存對象時會嘗試在新的 資料庫中使用這個主鍵。如果 second資料庫中沒有使用這個主鍵,那就不會有問題, 該對象會復制到新資料庫。
然而,如果 p 的主鍵在 second 資料庫中已經使用過了,那麼 second 使用 這個主鍵的已存在的對象將會被 p 覆蓋。
有兩種方法可以避免上述情況的發生。第一,你可以清除實例的主鍵。如果一個對象沒有 主主鍵,那麼 Django 會把它看作一個新對象,在保存到 second 資料庫中時就不會 帶來數據的損失:
>>> p = Person(name='Fred') >>> p.save(using='first') >>> p.pk = None # 清除主鍵。 >>> p.save(using='second') # 寫入一個全新的對象。
第二種方法是在 save() 方法中使用 force_insert 選項來保證 Django 執行 一個 INSERT SQL:
>>> p = Person(name='Fred') >>> p.save(using='first') >>> p.save(using='second', force_insert=True)
這樣可以保證名為 Fred 的人員在兩個資料庫中使用相同的主鍵。如果在保存到 second 資料庫時主鍵已被佔用,會拋出一個錯誤。
選擇一個要刪除數據的資料庫
預設情況下,一個現存對象從哪個資料庫得到,刪除這個對象也會在這個資料庫中進行:
>>> u = User.objects.using('legacy_users').get(username='fred') >>> u.delete() # 會從 `legacy_users` 資料庫中刪除
通過向 Model.delete() 方法傳遞 using 關鍵字參數可以定義在哪個資料庫中刪除 數據。 using 的用法與 save() 方法中使用這個參數類似。
例如,假設我們要把一個用戶從 legacy_users 資料庫移動到 new_users 資料庫 可以使用如下命令:
>>> user_obj.save(using='new_users') >>> user_obj.delete(using='legacy_users')
多資料庫情況下使用管理器
在管理器上使用 db_manager() ,可以讓管理器訪問一個非預設資料庫。
例如,假設你有一個操作資料庫的自定義管理器 User.objects.create_user() 。
因為 create_user() 是一個管理器方法,不是一個 查詢集 ,所以你不能
用 User.objects.using('new_users').create_user() 。( create_user() 方法
只能用於 User.objects 管理器,而不能用於,管理器衍生出的 查詢集 。) 解決方法是使用 db_manager() ,就象下面這樣:
User.objects.db_manager('new_users').create_user(...)
db_manager() 返回的是綁定到你指定的資料庫的管理器的一個副本。
多資料庫情況下使用 get_query_set()
如果你在管理器中重載了 get_query_set() ,請確保在其父類中也調用了相同的方法 (使用 super() )或者正確處理管理器中的 _db 屬性(一個包含要使用的資料庫 名稱的字元串)。
例如,如果你要從 get_query_set 方法返回一個自定義 查詢集 類,那麼你可以 這樣做:
class MyManager(models.Manager): def get_query_set(self): qs = CustomQuerySet(self.model) if self._db is not None: qs = qs.using(self._db) return qs
在 Django 管理介面中使用多資料庫
Django 的管理介面沒有明顯支持多資料庫。如果想要支持的話你必須寫自定義 ModelAdmin 。
如果要支持多資料庫,那麼 ModelAdmin 對象有五個方法要自定義:
class MultiDBModelAdmin(admin.ModelAdmin): # 為方便起見定義一個資料庫名稱常量。 using = 'other' def save_model(self, request, obj, form, change): # 讓 Django 保存對象到 'other' 資料庫。 obj.save(using=self.using) def delete_model(self, request, obj): # 讓 Django 從 'other' 資料庫中刪除對象。 obj.delete(using=self.using) def queryset(self, request): # 讓 Django 在 'other' 資料庫中搜索對象。 return super(MultiDBModelAdmin, self).queryset(request).using(self.using) def formfield_for_foreignkey(self, db_field, request=None, **kwargs): # 讓 Django 基於 'other' 資料庫生成外鍵控制項。 return super(MultiDBModelAdmin, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs) def formfield_for_manytomany(self, db_field, request=None, **kwargs): # 讓 Django 基於 'other' 資料庫生成多對多關系控制項。 return super(MultiDBModelAdmin, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)
㈡ django中怎麼動態操作資料庫欄位
django的ORM系統不支持修改刪除欄位的操作,也就是說你在寫模型model文件的時候,比如說定義了這個user表,然後包含欄位telphone定義,你一旦執行了manage.py syncdb 這個操作,就把表結構往資料庫寫死了,如果你之是刪除了model文件的telphone,資料庫是不被重新修改的。這個時候必須用原生SQL解決,也就是說自己寫SQL語句讓django執行,這樣的話會出很多問題,也就是說你執行了alter table users drop column telphone之後,你的model文件不知道你已經對users表結構做了修改,這樣會出直接導致django應用的崩潰。所以動態欄位不好做。也可能是我才疏學淺,沒太理解,也許有高人能做到。不過面對ORM這樣的盡量別刪除欄位。
㈢ django怎麼從資料庫取數據
Django 擁有自者沒己的森緩ORM模塊。
通俗來講其過首春納程如下:
在Django中寫Python 代碼
將Python代碼通過ORM模塊轉換成SQL語句
通過類似pymysql等資料庫操作模塊,使用SQL語句,前往資料庫訪問數據
上述過程的反方向
獲取Python格式的數據
㈣ Django裡面怎麼實現資料庫視圖啊 就是虛擬表
正經回答:先在資料庫中建立好視圖,然後django中建立對應的model。表所對應的類下面再建立一個Meta類,大致如下
classViewModel(models.Model):
"""這個model類對應你所建立好的視圖"""
classMeta(object):
"""同理,該方法可用於使用mysql中任何已有的表,不僅是視圖"""
db_table='your_view'#顯式指定表名,也就是你建立的視圖的名字
managed=false#默認是ture,設成falsedjango將不會執行建表和刪表操作
#建立欄位間的映射
#需要注意的是,必須設一個欄位為主鍵
#不然django會自動創建一個id欄位為主鍵,引發錯誤
網路知道越來越辣雞了,全是答非所問的。
㈤ django資料庫使用(django操作mysql資料庫)
在燃枝django程序外部使用djangomodels,我給你端示例代碼你看看:
fromdjango.core.managementimportsetup_environ
importQB.settings
setup_environ(QB.settings)
fromrecharge.modelsimportOrder,QB是我的project名稱,recharge是我的枝衡app名稱皮搭敏
㈥ 如何獨立使用django的資料庫訪問功能
1. 安裝Django
[plain] view plain
cd Django-1.4
python setup.py install
2. 安裝postgresql的客戶端:
[plain] view plain
sudo apt-get install -y postgresql-client-9.1 python-psycopg2
3. 新建project:
[plain] view plain
django-admin.py startproject myproject
4. 在myproject下新建app:
[plain] view plain
python manage.py startapp myapp
4. 新增環境變數:
編輯/etc/profile文件,在末尾加入以下語句:
[plain] view plain
<span style="color:#FF0000;"> export PYTHONPATH=$PYTHONPATH:/home/yc/src/myproject
export DJANGO_SETTINGS_MODULE=myproject.settings</span>
5.
假設資料庫已經由Django的另一個應用(名稱為otherapp)建好,資料庫類型是postgresql,名稱為mydb,位於
192.168.1.23。見好的資料庫中有一個表,名稱是otherapp_user,則將otherapp/models.py拷貝到myapp
/models.py。
注意檢查models.py下的class user類的class Meta:部分,如果沒有applabel標簽,則要加上:app_label='otherapp'
再修改/home/yc/src/myproject下的settings.py文件,如下:
[plain] view plain
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'mydb', # 'vps2db_test1' Or path to database file if using sqlite3.
'USER': 'postgres', # Not used with sqlite3.
'PASSWORD': '123', # Not used with sqlite3.
'HOST': '192.168.1.23', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '5432', # Set to empty string for default. Not used with sqlite3.
}
}
[plain] view plain
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'<span style="color:#FF0000;">myapp</span>',
)
6. 在myapp目錄下編寫測試程序
[python] view plain
from models import user
if __name__=="__main__":
try:
u = user.objects.get(id=user_id)
except user.DoesNotExist:
print "user not exist)
return None
else:
return u
㈦ 如何在django中使用多個資料庫
多個資料庫聯用時數據導入導出
使用的時候和一個資料庫的區別是:
如果不是defalut(默認資料庫)要在命令後邊加 --database=資料庫對應的settings.py中的名稱 如: --database=db1 或 --database=db2
資料庫同步(創建表)
python manage.py syncdb #同步默認的資料庫,和原來的沒有差讓區別
#同步資料庫 db1 (注意:不是資料庫名是db1,是settings.py中世塵的那個db1,不過你可以使這兩個名稱相同,容易使用)
python manage.py syncdb --database=db1
數虛返局據導出
python manage.py mpdata app1 --database=db1 > app1_fixture.json
python manage.py mpdata app2 --database=db2 > app2_fixture.json
python manage.py mpdata auth > auth_fixture.json
資料庫導入
python manage.py loaddata app1_fixture.json --database=db1
python manage.py loaddata app2_fixture.json --database=db2
㈧ django在sae怎麼用資料庫
"在Django項目的setting.py文件中將資料庫配置部分改成以下內容:"
try:
import sae.const
except Exception, e:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': '', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # 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.
}
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': sae.const.MYSQL_DB, # Or path to database file if using sqlite3.
'USER': sae.const.MYSQL_USER, # Not used with sqlite3.
'PASSWORD': sae.const.MYSQL_PASS, # Not used with sqlite3.
'HOST': sae.const.MYSQL_HOST, # Set to empty string for localhost. Not used with sqlite3.
'PORT': sae.const.MYSQL_PORT, # Set to empty string for default. Not used with sqlite3.
}
}
㈨ 如何在django中使用多個資料庫
在配置里將資料庫路徑放進去。然後在mole里,自己選擇相應的庫與相應的model做關段殲顫聯。
此外還可以指定表格中的欄位名改並。另外如果上面的方法不好用,你也可以握敗自己直接連接資料庫,自己管理。
django的資料庫連接是沒有連接池的。 每次訪問都連接一次,效率低。不過你也可以用同樣的原理 ,用mysqldb之類的庫,自己建立資料庫連接。
㈩ pycharm下的django怎麼連接mysql資料庫啊
方法/步驟
修改setting.py裡面的DATABASES元組為
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'books', #你的資料庫名稱
'USER': 'root', #你的資料庫用戶名
'PASSWORD': '', #你的資料庫密碼
'HOST': '', #你的資料庫主機,留空默認為localhost
'PORT': '3306', #你的資料庫埠
}
}
INSTALLED_APPS = (
'books',#你的資料庫名稱
)
在mysql裡面創建books資料庫
檢查配置是否有語法錯誤
使用python manage.py sqlall books 顯示mysql語法
使用python manage.py syncdb同步模型中的資料庫
創建成功!