问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

django怎么做数据库的(django怎么实现从数据库获取)

发布网友 发布时间:2024-10-01 12:04

我来回答

1个回答

热心网友 时间:2024-10-21 23:29

导读:很多朋友问到关于django怎么做数据库的的相关问题,本文首席CTO笔记就来为大家做个详细解答,供大家参考,希望对大家有所帮助!一起来看看吧!

如何在django中使用多个数据库

使用多个数据库

NewinDjango1.2:Please,seethereleasenotes

大多数其他文档都假设使用单一数据库,本文主要讨论如何在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.pysyncdb

$./manage.pysyncdb--database=users

如果你不是同步所有的程序到同一个数据库中,你可定义一个数据库路由来为指定的模型实施特定的控制策略。

如果你要精细地控制同步,那么还有一种方式是修改sqlall的输出,手工在数据库中执行命令,命令如下:

$./manage.pysqlallsales|./manage.pydbshell

使用其他管理命令

其他操作数据库的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数据库。本例使用了两个路由:

classMyAppRouter(object):"""一个控制myapp应用中模型的所有数据库操作的路由"""defdb_for_read(self,model,**hints):"myapp应用中模型的操作指向'other'"ifmodel._meta.app_label=='myapp':return'other'returnNonedefdb_for_write(self,model,**hints):"myapp应用中模型的操作指向'other'"ifmodel._meta.app_label=='myapp':return'other'returnNonedefallow_relation(self,obj1,obj2,**hints):"如果包含myapp应用中的模型则允许所有关系"ifobj1._meta.app_label=='myapp'orobj2._meta.app_label=='myapp':returnTruereturnNonedefallow_syncdb(self,db,model):"确保myapp应用只存在于'other'数据库"ifdb=='other':returnmodel._meta.app_label=='myapp'elifmodel._meta.app_label=='myapp':returnFalsereturnNoneclassMasterSlaveRouter(object):"""一个设置简单主/从定义的路由"""defdb_for_read(self,model,**hints):"所有读操作指向一个随机的从数据库"returnrandom.choice(['slave1','slave2'])defdb_for_write(self,model,**hints):"所有写操作指向主数据库"return'master'defallow_relation(self,obj1,obj2,**hints):"允许数据库池中的两个对象间的任何关系"db_list=('master','slave1','slave2')ifobj1._state.dbindb_listandobj2._state.dbindb_list:returnTruereturnNonedefallow_syncdb(self,db,model):"显示地放置所有数据库中的模型"returnTrue

然后在你的设置文件增加如下内容(把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='DouglasAdams')#新对象创建时还没有分配数据库mh=Book(title='MostlyHarmless')#这个赋值会向路由发出请求,并把mh的数据库设置为与author对象同样的#数据库mh.author=dna#这会强制'mh'实例使用主数据库...mh.save()#...但如果我们重新获取对象,就会从从数据库中获取mh=Book.objects.get(title='MostlyHarmless')

手动选择数据库

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执行了一个INSERTSQL语句。这样就会创建一个主键,并将这个主键分配给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执行一个INSERTSQL:

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方法返回一个自定义查询集类,那么你可以这样做:

classMyManager(models.Manager):defget_query_set(self):qs=CustomQuerySet(self.model)ifself._dbisnotNone:qs=qs.using(self._db)returnqs

在Django管理接口中使用多数据库

Django的管理接口没有明显支持多数据库。如果想要支持的话你必须写自定义ModelAdmin。

如果要支持多数据库,那么ModelAdmin对象有五个方法要自定义:

classMultiDBModelAdmin(admin.ModelAdmin):#为方便起见定义一个数据库名称常量。using='other'defsave_model(self,request,obj,form,change):#让Django保存对象到'other'数据库。obj.save(using=self.using)defdelete_model(self,request,obj):#让Django从'other'数据库中删除对象。obj.delete(using=self.using)defqueryset(self,request):#让Django在'other'数据库中搜索对象。returnsuper(MultiDBModelAdmin,self).queryset(request).using(self.using)defformfield_for_foreignkey(self,db_field,request=None,**kwargs):#让Django基于'other'数据库生成外键控件。returnsuper(MultiDBModelAdmin,self).formfield_for_foreignkey(db_field,request=request,using=self.using,**kwargs)defformfield_for_manytomany(self,db_field,request=None,**kwargs):#让Django基于'other'数据库生成多对多关系控件。returnsuper(MultiDBModelAdmin,self).formfield_for_manytomany(db_field,request=request,using=self.using,**kwargs)

django怎样自动创建数据库table

;

django创建数据库表方法如下:

catcher:mysite?catcher$?python?manage.py?makemigrations?books

Migrations?for?'books':

??0001_initial.py:

????-?Create?model?Author

????-?Create?model?Book

????-?Create?model?Publisher

????-?Add?field?publisher?to?book

catcher:mysite?catcher$?python?manage.py?sqlmigrate?books?0001

BEGIN;

--

--?Create?model?Author

--

CREATE?TABLE?"books_author"?("id"?integer?NOT?NULL?PRIMARY?KEY?AUTOINCREMENT,?"first_name"?varchar(30)?NOT?NULL,?"last_name"?varchar(40)?NOT?NULL,?"email"?varchar(254)?NOT?NULL);

--

--?Create?model?Book

--

CREATE?TABLE?"books_book"?("id"?integer?NOT?NULL?PRIMARY?KEY?AUTOINCREMENT,?"title"?varchar(100)?NOT?NULL,?"publication_date"?date?NOT?NULL);

CREATE?TABLE?"books_book_authors"?("id"?integer?NOT?NULL?PRIMARY?KEY?AUTOINCREMENT,?"book_id"?integer?NOT?NULL?REFERENCES?"books_book"?("id"),?"author_id"?integer?NOT?NULL?REFERENCES?"books_author"?("id"));

--

--?Create?model?Publisher

--

CREATE?TABLE?"books_publisher"?("id"?integer?NOT?NULL?PRIMARY?KEY?AUTOINCREMENT,?"name"?varchar(30)?NOT?NULL,?"address"?varchar(50)?NOT?NULL,?"city"?varchar(60)?NOT?NULL,?"state_province"?varchar(30)?NOT?NULL,?"country"?varchar(50)?NOT?NULL,?"website"?varchar(200)?NOT?NULL);

--

--?Add?field?publisher?to?book

--

ALTER?TABLE?"books_book"?RENAME?TO?"books_book__old";

CREATE?TABLE?"books_book"?("id"?integer?NOT?NULL?PRIMARY?KEY?AUTOINCREMENT,?"title"?varchar(100)?NOT?NULL,?"publication_date"?date?NOT?NULL,?"publisher_id"?integer?NOT?NULL?REFERENCES?"books_publisher"?("id"));

INSERT?INTO?"books_book"?("publication_date",?"publisher_id",?"id",?"title")

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
怎么养好四季海棠? 西安财神庙攻略,西安旅游攻略财神庙路线 漯河食品职业学院是几本 漯河食品职业学院是985还是211 做无痛人流的危害 地暖水压能保持多久 地暖水压维持时间有多长 海棠花开完花后该怎么处理 漯河食品职业学院为什么能升本 漯河食品职业学院质量检验系培养目标 漯河食品职业学院是谁建的 MySQL解析万能类数据库管理系统mysql万能类 聚会的主要目的 聚会的目的应该是什么 河北省500强企业名单 我家的车是老款捷达,跑了6万多公里,以前是一档和5档不好挂,后来我爸修... 老款捷达挂档机构怎么拆装? 江西三清山风景名胜区自驾车游三清山建议 江西三清山可以自驾车上山吗 电脑发邮件可以定时发送吗? 共益债务的申报 转正需要无犯罪记录吗 共益债务共益债权应当由债权人申报 企业APP开发意义 企业APP开发意义是什么 有哪些选购食用黄油的技巧分享? 有哪些判断黄油品质的技巧分享? 抽油烟机排风口这是什么意思? 用微波炉加工食物的九大禁忌 食堂油烟管道清洗报价 微波炉使用大忌有哪些 为什么要进行X2测验? 今天发现眼睛出现血块 不痛不痒 不知道是什么原因 该不该马上就医 眼睛里有象血块样的东西,不痛不痒是怎么回事? 左眼球眼白有血块,不痛不痒,也不影响视力,是怎么回事? ...不痛不痒就是感觉到眼睛累,都好久了这是怎么回事啊!急需帮_百度知 ... 我的眼睛有血块,最近才出现,不痛也不痒,一点感觉也没有,想请问一下这... 仙剑三中抢土灵珠的人共有多少滴血 圣斗士星矢144人游戏中人有多少滴血 有关思修社会实践报告 热水器触摸按钮有哪些 ios9.1 5s 电信4g如何破解 a1533美v版 大雾什么什么 苹果5s蜂窝移动数据里的当期时间210mb可短信里查的是150mb才用了... iPhone5S升级ios9.1经常提示运营商更新,这是什么情况?按了更新之后也频... 苹果5s升级到ios9怎么改字体 联通刚携号转网联通就被坑了,联通作为三大运营商,垫底不是没有理由... ...协议只收了定金,转让费和房租没给,就只有没跟房东签租赁合同,我可以... ...有残疾证书,但是不小心放衬衣口袋里洗衣服时没拿出来,弄坏了,在什 ... 什么是法律援助,法律援助的形式有什么? 我的军人残疾证洗衣服时不小心洗坏了,有什么办法补办吗? 残疾证洗衣服洗了,但一页不不缺不好了能补吗?