是否可以在不同的数据库上使用外键字段的模型? 例如:
class MultiBDModel(models.Model):
db1_user = models.ForeignKey(User) # here suppose to be foreign key on `db1`
db2_user = models.ForeignKey(User) # and here on `db2`
也许以某种方式复制用户。申请自定义经理。使用='db1'
返回查询集settings.py
中的:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'db1', # 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.
},
'website': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'db2', # 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. # Set to empty string for default. Not used with sqlite3.
}
}
答案 0 :(得分:1)
没有。 ORM无法执行数据库引擎无法执行的任何操作。
答案 1 :(得分:1)
没有。正如@ ignacio-vazquez-abrams所写,一个模型必须在同一个数据库中包含所有字段。
作为替代方案,您可以使用代理模型链接来自两个不同数据库的模型。
一个模型应该同时提供db1和db2中的字段
ContactMessage
,我们将其命名为legacy_db
。我们假设你不想接触这个模型,因为它来自另一个项目。ProxyContactMessage
,其属性与ContactMessage
相同。legacy_db
个ProxyContactMessage
对象中查找的位置。ExtendedContactMessage
。使用OneToOneField
声明ProxyContactMessage
。此数据将保存到您的db2 django_db
。ExtendedContactMessage
对象(如果有的话)。添加你想要的callables。在legacy_app/models.py
中,db1 legacy_db
上的模型为:
class ContactMessage(models.Model):
subject = models.CharField(max_length=255)
message = models.TextField()
created_at = models.DateTimeField()
created_by = models.CharField(max_length=255)
class Meta:
managed = False
db_table = 'contact_message'
def __unicode__(self):
return self.subject
因此,您可以在myapp/models.py
中创建:
class ProxyContactMessage(ContactMessage):
class Meta:
proxy = True
verbose_name = 'Contact message'
verbose_name_plural = 'Contact messages'
def add_extension(self):
e = ExtendedContactMessage(contact_message=self)
e.save()
return e
def mark_as_processed(self):
try:
e = self.extendedcontactmessage
except ExtendedContactMessage.DoesNotExist:
e = self.add_extension()
e.mark_as_processed()
def processed(self):
return self.extendedcontactmessage.processed
def processed_at(self):
return self.extendedcontactmessage.processed_at
class ExtendedContactMessage(models.Model):
contact_message = models.OneToOneField(ProxyContactMessage)
processed = models.BooleanField(default=False, editable=False)
processed_at = models.DateTimeField(null=True, default=None, editable=False)
def mark_as_processed(self):
self.processed = True
self.processed_at = timezone.now()
self.save()
请注意,只有非抽象模型ExtendedContactMessage
将保存在db2中,因为ProxyContactMessage
是抽象的。
在settings.py
中,使用类
class LegacyRouter(object):
"""
A router to control all database operations on models in the
legacy database.
"""
def db_for_read(self, model, **hints):
if model.__name__ == 'ProxyContactMessage':
return 'legacy_db'
return None
def db_for_write(self, model, **hints):
"""
Attempts to write in legacy DB for ContactMessage.
"""
if model.__name__ == 'ProxyContactMessage':
return 'legacy_db'
return None
您的默认路由器将所有内容发送到db2。
最后你可能有一个管理类,如:
def mark_as_processed(modeladmin, request, queryset):
for obj in queryset:
obj.mark_as_processed()
mark_as_processed.short_description = "Mark as processed"
class ProxyContactMessageAdmin(admin.ModelAdmin):
list_display = (
'subject',
'message',
'created_at',
'created_by',
'processed',
'processed_at',
)
actions = (mark_as_processed,)
admin.site.register(ProxyContactMessage, ProxyContactMessageAdmin)
相关: