Короткий ответ: , это зависит.
Длинный ответ заключается в том, что это зависит от того, что вы храните вместе с маркой указанных автомобилей и как часто вы ожидаете добавлять новые типы.
Если вам нужно хранить не только название каждой марки, но и некоторые дополнительные метаданные, такие как размер бензобака, размер автомобиля go или даже сортировочный ключ, go для дополнительная таблица. Затраты на такую маленькую таблицу минимальны, и если вы общаетесь с внешним интерфейсом, используя make ids вместо make names , с этим вообще не возникает никаких проблем. Просто не забудьте добавить индекс к vehicle.make_id
, чтобы сделать поиск более эффективным.
class VehicleMake(Model):
id = Column(Integer, primary_key=True)
name = Column(String(16))
cars = relationship('Vehicle', back_populates="make", lazy='dynamic')
class Vehicle(Model):
id = Column(Integer, primary_key=True)
name = Column(String(32))
make_id = Column(Integer, ForeignKey('vehicle_make.id'), nullable=False)
make = relationship("VehicleType", innerjoin=True)
Vehicle.query.get(1).make.name # == 'Ford', the make for vehicle 1
Vehicle.query.filter(Vehicle.make_id == 2).all() # all Vehicles with make id 2
Vehicle.query.join(VehicleMake)\
.filter(VehicleMake.name == 'Ford').all() # all Vehicles with make name 'Ford'
Если вам не нужно хранить какие-либо из этих метаданных, то необходимость в отдельной таблице исчезает. Тем не менее, общая проблема со строками состоит в том, что существует высокий риск орфографических ошибок и заглавных / строчных букв, которые нарушают целостность данных. Если вам не нужно много добавлять новых марок, гораздо лучше просто использовать Enums , в SQLAlchemy есть даже MySQL speci c.
import enum
class VehicleMake(enum.Enum):
FORD = 1
DODGE = 2
CHEVROLET = 3
class Vehicle(Model):
id = Column(Integer, primary_key=True)
name = Column(String(32))
make = Column(Enum(VehicleMake), nullable=False)
Vehicle.query.get(1).make.name # == 'FORD', the make for vehicle 1
Vehicle.query.filter(Vehicle.make == VehicleMake(2)).all() # all Vehicles with make id 2
Vehicle.query.filter(Vehicle.make == VehicleMake.FORD).all() # all Vehicles with make name 'Ford'
Основной недостаток перечислений в том, что их может быть сложно расширить новыми значениями, хотя по крайней мере для Postgres версия диалекта c была намного лучше, чем общая версия SQLAlchemy, посмотрите на sqlalchemy.dialects.mysql.ENUM
вместо. Хотя, если вы хотите расширить существующий enum, вы всегда можете просто выполнить raw SQL в ваших Flask -Migrate / Alembi c миграциях.
Наконец, преимущества используя строки. Главным образом, это то, что вы всегда можете программно обеспечить согласованность данных. Но это происходит за счет того, что вы должны программно обеспечить согласованность данных. Если внешний вид автомобиля может быть изменен или вставлен внешними пользователями, даже коллегами, это доставит вам неприятности, если вы не будете очень строги в отношении того, что входит в вашу базу данных. Например, было бы неплохо прописать все значения в верхнем регистре для упрощения группировки, поскольку это эффективно уменьшает то, что go может ошибаться. Вы можете сделать это во время записи или добавить индекс на sqlalchemy.func.upper(Vehicle.make)
и использовать гибридные свойства , чтобы всегда запрашивать значение в верхнем регистре.
class Vehicle(Model):
id = Column(Integer, primary_key=True)
name = Column(String(32))
_make = Column('make', String(16))
@hybrid_property
def make(self):
return self._make.upper()
@make.expression
def make(cls):
return func.upper(cls._make)
Vehicle.query.get(1).make.upper() # == 'FORD', the make for vehicle 1
Vehicle.query.filter(Vehicle.make == 'FORD').all() # all Vehicles with make name 'FORD'
Прежде чем сделать свой выбор, также подумайте, как вы хотите представить это своему пользователю. Если они смогут самостоятельно добавлять новые параметры, используйте строки или отдельную таблицу. Если вы хотите показать раскрывающийся список возможностей, используйте перечисление или таблицу. Если у вас есть пустая база данных, будет трудно собрать все строковые значения для отображения во внешнем интерфейсе без необходимости сохранять их как список где-то в вашей среде Flask.