126 lines
4.0 KiB
Python
126 lines
4.0 KiB
Python
import databases
|
|
import pytest
|
|
import sqlalchemy
|
|
|
|
import orm
|
|
from tests.settings import DATABASE_URL
|
|
|
|
database = databases.Database(DATABASE_URL, force_rollback=True)
|
|
metadata = sqlalchemy.MetaData()
|
|
|
|
|
|
class Department(orm.Model):
|
|
__tablename__ = "departments"
|
|
__metadata__ = metadata
|
|
__database__ = database
|
|
|
|
id = orm.Integer(primary_key=True, autoincrement=False)
|
|
name = orm.String(length=100)
|
|
|
|
|
|
class SchoolClass(orm.Model):
|
|
__tablename__ = "schoolclasses"
|
|
__metadata__ = metadata
|
|
__database__ = database
|
|
|
|
id = orm.Integer(primary_key=True)
|
|
name = orm.String(length=100)
|
|
department = orm.ForeignKey(Department, nullable=False)
|
|
|
|
|
|
class Category(orm.Model):
|
|
__tablename__ = "categories"
|
|
__metadata__ = metadata
|
|
__database__ = database
|
|
|
|
id = orm.Integer(primary_key=True)
|
|
name = orm.String(length=100)
|
|
|
|
|
|
class Student(orm.Model):
|
|
__tablename__ = "students"
|
|
__metadata__ = metadata
|
|
__database__ = database
|
|
|
|
id = orm.Integer(primary_key=True)
|
|
name = orm.String(length=100)
|
|
schoolclass = orm.ForeignKey(SchoolClass)
|
|
category = orm.ForeignKey(Category, nullable=True)
|
|
|
|
|
|
class Teacher(orm.Model):
|
|
__tablename__ = "teachers"
|
|
__metadata__ = metadata
|
|
__database__ = database
|
|
|
|
id = orm.Integer(primary_key=True)
|
|
name = orm.String(length=100)
|
|
schoolclass = orm.ForeignKey(SchoolClass)
|
|
category = orm.ForeignKey(Category, nullable=True)
|
|
|
|
|
|
@pytest.fixture(autouse=True, scope="module")
|
|
def create_test_database():
|
|
engine = sqlalchemy.create_engine(DATABASE_URL)
|
|
metadata.create_all(engine)
|
|
yield
|
|
metadata.drop_all(engine)
|
|
|
|
|
|
@pytest.fixture()
|
|
async def init_relation():
|
|
department = await Department.objects.create(id=1, name="Math Department")
|
|
class1 = await SchoolClass.objects.create(name="Math", department=department)
|
|
category = await Category.objects.create(name="Foreign")
|
|
category2 = await Category.objects.create(name="Domestic")
|
|
await Student.objects.create(name="Jane", category=category, schoolclass=class1)
|
|
await Student.objects.create(name="Jack", category=category2, schoolclass=class1)
|
|
await Teacher.objects.create(name="Joe", category=category2, schoolclass=class1)
|
|
yield
|
|
engine = sqlalchemy.create_engine(DATABASE_URL)
|
|
metadata.drop_all(engine)
|
|
metadata.create_all(engine)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_model_multiple_instances_of_same_table_in_schema(init_relation):
|
|
async with database:
|
|
classes = await SchoolClass.objects.select_related(
|
|
["teachers__category", "students"]
|
|
).all()
|
|
assert classes[0].name == "Math"
|
|
assert classes[0].students[0].name == "Jane"
|
|
|
|
# related fields of main model are only populated by pk
|
|
# unless there is a required foreign key somewhere along the way
|
|
# since department is required for schoolclass it was pre loaded (again)
|
|
# but you can load them anytime
|
|
assert classes[0].students[0].schoolclass.name == "Math"
|
|
assert classes[0].students[0].schoolclass.department.name is None
|
|
await classes[0].students[0].schoolclass.department.load()
|
|
assert classes[0].students[0].schoolclass.department.name == "Math Department"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_right_tables_join(init_relation):
|
|
async with database:
|
|
classes = await SchoolClass.objects.select_related(
|
|
["teachers__category", "students"]
|
|
).all()
|
|
assert classes[0].teachers[0].category.name == "Domestic"
|
|
|
|
assert classes[0].students[0].category.name is None
|
|
await classes[0].students[0].category.load()
|
|
assert classes[0].students[0].category.name == "Foreign"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_multiple_reverse_related_objects(init_relation):
|
|
async with database:
|
|
classes = await SchoolClass.objects.select_related(
|
|
["teachers__category", "students"]
|
|
).all()
|
|
assert classes[0].name == "Math"
|
|
assert classes[0].students[1].name == "Jack"
|
|
assert classes[0].teachers[0].category.name == "Domestic"
|