python - 在peewee中跨多个数据库使用多个M2M关系
问题描述
我有两个 python 项目,它们维护它们不同的数据库连接和 sqlite 文件。model1.py
是在低级项目中,model2.py
是在使用模型类的高级项目中model1.py
。以下是示例代码:
模型1.py
from os.path import join, dirname
from peewee import *
from playhouse.sqlite_ext import *
_db = SqliteDatabase(join(dirname(__file__), 'db1.sqlite'))
class Student(Model):
name = CharField()
sex = CharField()
class Meta:
database = _db
def __str__(self):
return 'student name: %s, sex: %s' % (self.name, self.sex)
_db.connect()
_db.create_tables([
Student,
])
模型2.py
from os.path import join, dirname
from peewee import *
from playhouse.sqlite_ext import *
from model1 import *
_db = SqliteDatabase(join(dirname(__file__), 'db2.sqlite'))
class Teacher(Model):
name = CharField()
age = IntegerField()
sample_student = ForeignKeyField(Student, null=True, backref='sample_teacher')
students = ManyToManyField(Student, backref='teachers')
class Meta:
database = _db
def __str__(self):
return 'teacher name: %s, age: %d' % (self.name, self.age)
_db.connect()
_db.create_tables([
Teacher,
Teacher.students.get_through_model(),
])
主文件
from model1 import *
from model2 import *
if __name__ == '__main__':
Teacher.students.through_model.delete().execute()
Teacher.delete().execute()
Student.delete().execute()
s1 = Student.create(name='s1', sex='male')
s2 = Student.create(name='s2', sex='female')
t1 = Teacher.create(name='t1', age=20)
t1.students.add(s1)
t1.students.add(s2)
t1.sample_student = s1
t1.save()
print(t1.sample_student) # ForeignKeyField works!
[print(s) for s in Student.select()]
[print(t) for t in Teacher.select()]
for s in t1.students: # crash here: peewee.OperationalError: no such table: teacher_student_through
print(s)
对于表teacher_student_through
,它实际上存在于db2.sqlite
数据库中。那么,这是peewee
我的错误还是错误使用?
解决方案
我没有使用数据库对象,而是为我的 python 包重新设计了带有数据库代理Meta.database
的元模型初始化。
_db_proxy = DatabaseProxy()
class PeeweeModel(Model):
class Meta:
database = _db_proxy
# skip the other subclass models implementation here...
def setup_database(dbpath):
'''Initialize database.'''
database = SqliteDatabase(dbpath)
_db_proxy.initialize(database)
database.connect(reuse_if_open=True)
database.create_tables([
Model1,
Model2,
])
return database
包调用者现在有责任初始化数据库对象,请参阅有关此的更多文档。
公众PeeweeModel
也可以使用高级python包来扩展数据库表,只需将其用作通用超模型类即可。
推荐阅读
- django - 在 django 测试中过滤警告
- jenkins-pipeline - 将 salt minion id 从平面文件传递给 Jenkins 管道
- python - 当使用python使用下拉菜单时,如何在excel中更改整个行的颜色
- excel - 根据标题值复制/粘贴单元格
- python - 将实时条形图与折线图一起绘制
- rest - Coldfusion 11 - 添加 Rest API 服务主机问题
- postgresql - 更改列会锁定 postgresql 中的表吗?
- oracle - 在 oracle 钱包中指定证书和密钥
- android - 将两个视图放在屏幕中央
- android - 如何在 Android kotlin 中创建多级回收视图?