Проверьте, существует ли объект до создания нового с помощью SQL Alchemy / Python [duplicate]

На самом деле sed -n '/pattern/{n;p}' filename выйдет из строя, если pattern соответствует continuous линиям:

$ seq 15 |sed -n '/1/{n;p}'
2
11
13
15

Ожидаемые ответы должны быть:

2
11
12
13
14
15

Мое решение:

$ sed -n -r 'x;/_/{x;p;x};x;/pattern/!s/.*//;/pattern/s/.*/_/;h' filename

Например:

$ seq 15 |sed -n -r 'x;/_/{x;p;x};x;/1/!s/.*//;/1/s/.*/_/;h'
2
11
12
13
14
15

Объясняет:

  1. x;: в начале каждой строки из ввода используйте x для обмена содержимым в pattern space & amp; hold space.
  2. /_/{x;p;x};: если pattern space, который фактически является hold space, содержит _ (это только indicator, указывающий, соответствует ли последняя строка pattern или not), затем используйте x для обмена фактическим содержимым current line на pattern space, используйте p для печати current line и x для восстановления этой операции.
  3. x: восстановить содержимое в pattern space и hold space.
  4. /pattern/!s/.*//: если current line НЕ соответствует pattern, это означает, что мы НЕ должны напечатайте следующую строку ниже, затем используйте команду s/.*//, чтобы удалить все содержимое в pattern space.
  5. /pattern/s/.*/_/: если current line соответствует pattern, это означает, что мы должны напечатать следующую строку ниже , тогда нам нужно установить indicator, чтобы сообщить sed распечатать строку NEXT, поэтому используйте s/.*/_/, чтобы заменить все содержимое в pattern space на _ (вторая команда будет использовать его, чтобы судить, если последняя строка соответствует pattern или нет).
  6. h: перезаписать hold space с содержимым в pattern space; то содержание в hold space равно ^_$, что означает, что current line соответствует pattern или ^$, что означает, что current line НЕ соответствует pattern.
  7. пятый шаг и шестой шаг не могут быть обменены, потому что после s/.*/_/, pattern space НЕ МОЖЕТ соответствовать /pattern/, поэтому s/.*// ДОЛЖЕН быть выполнен!
6
задан Thomas Spycher 18 November 2012 в 16:07
поделиться

2 ответа

есть именно этот пример на wiki в http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject .

Хотя совсем недавно я предпочитал использовать @classmethod для этого вместо того, чтобы переопределять конструктор, поскольку явный лучше, чем неявный, также проще:

user.email = Email.as_unique('foo@bar.com')

(я на самом деле собираюсь обновить wiki, чтобы более полно представить варианты использования здесь)

6
ответ дан zzzeek 22 August 2018 в 04:52
поделиться

Я думаю, что это не лучший способ достичь этого, поскольку он создает зависимость вашего конструктора от глобальной переменной session, а также неожиданно изменяет поведение конструктора (ожидается, что new возвращает new в конце концов). Если, например, кто-то использует ваши классы с двумя сеансами параллельно, код будет терпеть неудачу, и ему придется выкопать код, чтобы найти ошибку.

Я не знаю никакой «sqlalchemy», способ достижения этого, но я бы предложил создать функцию createOrGetAccountModel, подобную

def createOrGetAccountModel(**kw):
    if len(kw) and "name" in kw:
      x = session.query(AccountModel).filter_by(name=kw["name"]).first()
      if x: return x
    return AccountModel(**kw)
1
ответ дан MartinStettner 22 August 2018 в 04:52
поделиться
  • 1
    Твое право! Это не идеальное решение, касающееся ремонтопригодности кода. Но является ли новым не идеальным местом для манипулирования созданием объекта? – Thomas Spycher 19 November 2012 в 08:31
  • 2
    Да, но вы не всегда создаете новые объекты, поэтому __new__ вводит в заблуждение. Если вы напишете x=SomeClass(), все ожидают, что x станет новым объектом ... – MartinStettner 20 November 2012 в 22:36
Другие вопросы по тегам:

Похожие вопросы: