1

SQL から noSQL HDR に移行しているため、ちょっとした実装上の問題が発生しました。

私はページと呼ばれるモデルを持っています:

class Page(db.Model):
    url = db.StringProperty(required=True)
    title = db.StringProperty()
    enable_login = db.BooleanProperty(required=True, default=True)
    owner = db.ReferenceProperty(Person, collection_name = 'pages')
    date_created = db.DateTimeProperty(auto_now_add=True)
    date_edited = db.DateTimeProperty(auto_now=True)

ユーザーが登録するたびに、key_name として使用されていない一意のURL を使用してページが作成されます。これについては、いくつかの理由で説明したいと思います。

トランザクション内:

unique_url=hashlib.md5(str(person.key())).hexdigest()
page = Page(key_name=unique_url,parent=person, owner=person, title="Home page", name=person.nick_name, url=unique_url)

ユーザーが自分のページの URL を更新しようとすると、私の問題が発生します。ユーザーは自分のページの URL を 1 回だけ変更できます。ユーザーが新しいページ URL を送信すると、サーバーはその URL が存在するかどうかを確認し、存在しない場合はユーザー ページを更新します。

重複した URL が必要ないという事実のために、トランザクション内で再び:

def validate_page_properties(self, page):
  if not re.match("\A[A-Za-z]+\Z", page.url) or len(page.url) < 4 or len(page.url) > 20:
    return False
  page = Page.all().filter("url =",page.url).get()

エラー:

Only ancestor queries are allowed inside transactions.

この実装エラーを克服するにはどうすればよいですか?

URL は一意 (強制) であるため、key_name として設定しようとしましたが、すべてのページの親がユーザーであるため、完全なキーが必要です。親を持たないページに変更することはできますが、後で必要なトランザクションで再び問題が発生する可能性があります。

助言がありますか?ここで何か不足していますか?

4

1 に答える 1

1

まず、GAE トランザクションとトランザクション内で何ができるかを理解する必要があります。

あなたの場合、すでに人をページの親に設定しているため、クエリでのみ設定する必要があります。

 page = Page.all().ancestor(person).filter("url =",page.url).get()

更新:個人スコープのトランザクションを使用すると同時に、グローバルに一意のユーザー生成文字列をチェックすることはできません。個人に固有の(=ナンセンス)文字列があるか、スコープがグローバルでなければなりません。これは次の方法で実現できます。

  1. グローバルな親を使用 - ユーザーが送信したすべての URL の親である単一のエンティティ UniqueUrlParent を持ちます。書き込みはエンティティ グループごとに 5 回の書き込み/秒に制限されているため、これがボトルネックになります (これはグローバルなものしかありません)。
  2. Urls をキーとして使用しますが、それはしたくないと言っていました。なぜそうしないのか詳しく説明しますか?これを人間が読めないようにするために、ある種の双方向ハッシュを使用できます。
于 2012-12-17T11:14:52.343 に答える