5

我有一个遗留的 PostgreSQL 数据库,它有一个模型分成两个表,它们之间具有一对一的映射。

CREATE TABLE auth_user (
    id SERIAL,
    username VARCHAR(30),
    email VARCHAR(75),
    password VARCHAR(64),
    first_name VARCHAR(75),
    last_name VARCHAR(75)
)
CREATE TABLE user_profile (
    user_id INTEGER REFERENCES auth_User.id,
    phone VARCHAR(32)
)

不幸的是,我无法更改数据库结构。

我想将其用作单个 Sequel 模型。从数据库中检索数据按预期工作:

class User < Sequel::Model
end

# Variant 1: using LEFT JOIN
#User.set_dataset DB[:auth_user].left_join(:user_profile, :user_id => :id)

# Variant 2: using two FROM tables
User.set_dataset DB[:auth_user, :user_profile]\
                   .where(:auth_user__id => :user_profile__user_id)

user = User[:username => "root"] # This works.

但是,保存模型失败:

user.set :first_name => "John"
user.save                        # This fails.

如果我使用数据集的第一个变体(带有left_join),我会得到一个“ Need multiple FROM tables if updating/deleting a dataset with JOINs”错误。如果我使用第二种变体,它仍然会失败:“ PG::Error: ERROR: column "phone" of relation "auth_user" does not exist LINE 1: ..."email" = 'nobody@example.org', "password" = '!', "phone"...

有没有办法让 Sequel 无缝地发出两个 UPDATE 语句?(同样的问题也适用于 INSERT)。

4

1 回答 1

4

您可以拥有使用连接数据集的 Sequel 模型,但没有简单的方法可以保存这样的模型。

就个人而言,我会使用 many_to_one 关系、嵌套属性和挂钩来满足您的需求:

class UserProfile < Sequel::Model(:user_profile)
end
class User < Sequel::Model(:auth_user)
  many_to_one :user_profile, :key=>:id, :primary_key=>:user_id
  plugin :nested_attributes
  nested_attributes :user_profile

  def phone
    user_profile.phone
  end

  def phone=(v)
    user_profile.phone = v
  end

  def user_profile
    if s = super
      s
    else
      self.user_profile_attributes = {}
      super
    end
  end

  def before_destroy
    user_profile.destroy
    super
  end

  def before_create
    user_profile
    super
  end

  def after_update
    super
    user_profile.save
  end
end

我还没有测试过,但类似的东西应该可以工作。如果您对此有疑问,您可能应该在 sequel-talk Google Group 上发帖。

于 2012-06-14T16:20:47.110 回答