Django中一个项目使用多个数据库(原生sql 的使用,亲测)
在django項(xiàng)目中, 一個(gè)工程中存在多個(gè)APP應(yīng)用很常見(jiàn). 有時(shí)候希望不同的APP連接不同的數(shù)據(jù)庫(kù),這個(gè)時(shí)候需要建立多個(gè)數(shù)據(jù)庫(kù)連接。
參考:http://blog.csdn.net/songfreeman/article/details/70229839
?
1. 修改項(xiàng)目的 settings 配置?
在?settings.py?中配置需要連接的多個(gè)數(shù)據(jù)庫(kù)連接串
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | DATABASES?=?{ ????'default': { ????????'ENGINE':?'django.db.backends.sqlite3', ????????'NAME': os.path.join(BASE_DIR,?'db.sqlite3'), ????}, ????'ora1': {???# 配置第二個(gè)數(shù)據(jù)庫(kù)節(jié)點(diǎn)名稱 ????????'ENGINE':?'django.db.backends.oracle', ????????'NAME':?'devdb', ????????'USER':?'hysh', ????????'PASSWORD':?'hysh', ????????'HOST':?'192.168.191.3', ????????'PORT':?'1521', ????}, } |
2. 設(shè)置數(shù)據(jù)庫(kù)的路由規(guī)則方法?
在?settings.py?中配置?DATABASE_ROUTERS
| 1 | DATABASE_ROUTERS?=?['Prject.database_router.DatabaseAppsRouter'] |
Project: 建立的django項(xiàng)目名稱(project_name)?
database_router: 定義路由規(guī)則database_router.py?文件名稱, 這個(gè)文件名可以自己定義?
DatabaseAppsRouter: 路由規(guī)則的類名稱,這個(gè)類是在database_router.py?文件中定義
3. 設(shè)置APP對(duì)應(yīng)的數(shù)據(jù)庫(kù)路由表?
每個(gè)APP要連接哪個(gè)數(shù)據(jù)庫(kù),需要在做匹配設(shè)置,在?settings.py?文件中做如下配置:
| 1 2 3 4 5 6 7 | DATABASE_APPS_MAPPING?=?{ ????# example: ????# 'app_name':'database_name', ????'report':?'ora1', ????'admin':?'defualt', ????'regs':??'defualt', } |
以上的report,?regs是項(xiàng)目中的 APP名,分別指定到 ora1, default的數(shù)據(jù)庫(kù)。?
為了使django自己的表也創(chuàng)建到你自己定義的數(shù)據(jù)庫(kù)中,你可以指定 : admin, auth, contenttypes, sessions 到設(shè)定的數(shù)據(jù)庫(kù)中,如果不指定則會(huì)自動(dòng)創(chuàng)建到默認(rèn)(default)的數(shù)據(jù)庫(kù)中.
4. 創(chuàng)建數(shù)據(jù)庫(kù)路由規(guī)則?
在項(xiàng)目工程根路徑下(與 settings.py 文件一級(jí))創(chuàng)建?database_router.py?文件:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | from?django.conf?import?settings ? DATABASE_MAPPING?=?settings.DATABASE_APPS_MAPPING ? ? class?DatabaseAppsRouter(object): ????""" ????A router to control all database operations on models for different ????databases. ? ????In case an app is not set in settings.DATABASE_APPS_MAPPING, the router ????will fallback to the `default` database. ? ????Settings example: ? ????DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'} ????""" ? ????def?db_for_read(self, model,?**hints): ????????""""Point all read operations to the specific database.""" ????????if?model._meta.app_label?in?DATABASE_MAPPING: ????????????return?DATABASE_MAPPING[model._meta.app_label] ????????return?None ? ????def?db_for_write(self, model,?**hints): ????????"""Point all write operations to the specific database.""" ????????if?model._meta.app_label?in?DATABASE_MAPPING: ????????????return?DATABASE_MAPPING[model._meta.app_label] ????????return?None ? ????def?allow_relation(self, obj1, obj2,?**hints): ????????"""Allow any relation between apps that use the same database.""" ????????db_obj1?=?DATABASE_MAPPING.get(obj1._meta.app_label) ????????db_obj2?=?DATABASE_MAPPING.get(obj2._meta.app_label) ????????if?db_obj1?and?db_obj2: ????????????if?db_obj1?==?db_obj2: ????????????????return?True ????????????else: ????????????????return?False ????????return?None ? ????def?allow_syncdb(self, db, model): ????????"""Make sure that apps only appear in the related database.""" ? ????????if?db?in?DATABASE_MAPPING.values(): ????????????return?DATABASE_MAPPING.get(model._meta.app_label)?==?db ????????elif?model._meta.app_label?in?DATABASE_MAPPING: ????????????return?False ????????return?None ? ????def?allow_migrate(self, db, app_label, model=None,?**hints): ????????""" ????????Make sure the auth app only appears in the 'auth_db' ????????database. ????????""" ????????if?db?in?DATABASE_MAPPING.values(): ????????????return?DATABASE_MAPPING.get(app_label)?==?db ????????elif?app_label?in?DATABASE_MAPPING: ????????????return?False ????????return?None |
5.原生sql?的使用:
| 1 2 3 4 5 6 | def?exc_sql(sql): ????cursor?=?connections['ora1'].cursor() ????# cursor = connection.cursor() ????cursor.execute(sql) ????result?=?cursor.fetchall() ????return?result |
參考:https://docs.djangoproject.com/en/2.0/topics/db/sql/
?
6. Models創(chuàng)建樣例?
在各自的 APP 中創(chuàng)建數(shù)據(jù)表的models時(shí),必須要指定表的 app_label 名字,如果不指定則會(huì)創(chuàng)建到?default?中配置的數(shù)據(jù)庫(kù)名下,?
如下:
在app01下創(chuàng)建models
| 1 2 3 4 5 6 7 8 9 | class?Users(models.Model): ????name?=?models.CharField(max_length=50) ????passwd?=?models.CharField(max_length=100) ? ????def?__str__(self): ????????return?"app01 %s "?%?self.name ? ????class?Meta: ????????app_label?=?"app01" |
在app02下創(chuàng)建models
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class?Users(models.Model): ????username?=?models.CharField(max_length=100) ????password?=?models.CharField(max_length=50) ????age?=?models.IntegerField() ? ????def?__str__(self): ????????return?"app02 %s"?%?self.username ? ????class?Meta: ????????app_label?=?"app02" ? class?Book(models.Model): ????user?=?models.ForeignKey("Users", on_delete=models.CASCADE) ????bookname?=?models.CharField(max_length=100) ? ????def?__str__(self): ????????return?"%s: %s"?%?(self.user.username,?self.bookname) ? ????class?Meta: ????????app_label?=?"app02" |
7. 生成數(shù)據(jù)表?
在使用django的 migrate 創(chuàng)建生成表的時(shí)候,需要加上 –database 參數(shù),如果不加則將 未 指定 app_label 的 APP的models中的表創(chuàng)建到default指定的數(shù)據(jù)庫(kù)中,如:
將app01下models中的表創(chuàng)建到db01的數(shù)據(jù)庫(kù)”db_01”中
./ manage.py migrate --database=db01將app02下models中的表創(chuàng)建到db02的數(shù)據(jù)庫(kù)”db_02”中
./ manage.py migrate --database=db02將app03下models中的表創(chuàng)建到default的數(shù)據(jù)庫(kù)”sqlite3”中
./ manage.py migrate以上創(chuàng)建完成后,其它所有的創(chuàng)建、查詢、刪除等操作就和普通一樣操作就可以了,無(wú)需再使用類似?
models.User.objects.using(dbname).all()?
這樣的方式來(lái)操作
來(lái)源:https://www.cnblogs.com/fu-yong/p/9889423.html
總結(jié)
以上是生活随笔為你收集整理的Django中一个项目使用多个数据库(原生sql 的使用,亲测)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 新手炒股注意事项
- 下一篇: Django 多数据库联用(看着不错还有