Я создаю веб-приложение в Python 3, используя Flask & SQLAlchemy (через Flask-SQLAlchemy; с MySQL или SQLite), и я столкнулся с ситуацией, в которой я хотел бы сослаться на одно свойство в моемкласс модели, который инкапсулирует несколько столбцов в моей базе данных.Я довольно хорошо разбираюсь в MySQL, но это мой первый настоящий опыт освоения SQLAlchemy за рамками основ.Чтение документов, поиск SO и поиск в Google привели меня к двум возможным решениям: гибридные атрибуты ( документы ) или составные столбцы ( документы ).
Мой вопрос: каковы последствия использования каждого из них, и какое из них является подходящим решением для моей ситуации?Ниже приведен пример кода, который представляет собой фрагмент того, что я делаю.
Справочная информация: я разрабатываю приложение для отслеживания и сортировки фотографий и имею таблицу БД, в которой хранюметаданные для этих фотографий, в том числе, когда была сделана фотография.Так как фотографии сделаны в определенном месте, дата и время съемки имеют связанный часовой пояс.Поскольку SQL общеизвестно любит / ненавидит отношения с часовыми поясами, я решил записать, когда фотография была сделана в двух столбцах: дата-время, хранящее дату и время, и строка, хранящая имя часового пояса.(Я бы хотел обойти неизбежные дебаты о том, как хранить даты и время с учетом часового пояса в SQL, пожалуйста.) Что мне нужно, так это один параметр в классе модели, который я могу использовать для получения правильного объекта datetime Python,и что я также могу установить, как любой другой столбец.
Вот моя таблица:
class Photo(db.Model):
__tablename__ = 'photos'
id = db.Column(db.Integer, primary_key=True)
...
taken_dt = db.Column(db.datetime, nullable=False)
taken_tz = db.Column(db.String(64), nullable=False)
...
Вот то, что я использую гибридный параметр (добавленный к классу выше, код datetime / pytzpsuedocode):
@hybrid_parameter
def taken(self):
return datetime.datetime(self.taken_dt, self.taken_tz)
@taken.setter(self, dt):
self.taken_dt = dt
self.taken_tz = dt.tzinfo
Оттуда я не совсем уверен, что еще мне нужно на пути @taken.expression
или @taken.comparator
, или почему я бы выбрал одно из другого.
Вот что я использую, используя составной столбец (опять же, добавленный в вышеупомянутый класс, код datetime / pytz - psuedocode):
taken = composite(DateTimeTimeZone._make, taken_dt, taken,tz)
class DateTimeTimeZone(object):
def __init__(self, dt, tz):
self.dt = dt
self.tz = tz
@classmethod
def from_db(cls, dt, tz):
return DateTimeTimeZone(dt, tz)
@classmethod
def from_dt(cls, dt):
return DateTimeTimeZone(dt, dt.tzinfo)
def __composite_values__(self):
return (self.dt, self.tz)
def value(self):
#This is here so I can get the actual datetime.datetime object
return datetime.datetime(self.dt, self.tz)
Казалось бы, этот метод имеет приличное количество дополнительныхнакладные расходы, и я не могу придумать способ установить его так, как если бы я использовал любой другой столбец непосредственно из объекта datetime.datetime, не создавая экземпляр объекта-значения сначала, используя .from_dt
.
Любые указания относительно того, если я 'я иду внизнеправильный путь здесь будет приветствоваться.Спасибо!