
Calls to has 1 associations result in multiple db calls
Reported by Mark Bates | August 1st, 2008 @ 05:06 PM
I have a User object which has 1 UserProfile. When I make calls through user.user_profile to get properties off of it, it results in a DB query on each call. I found this in 0.9.3 and 0.9.4.
Here is my slimmed down classes:
require 'rubygems'
require 'dm-core'
require 'dm-validations'
require 'dm-timestamps'
require 'dm-aggregates'
DataMapper.logger = DataMapper::Logger.new(STDOUT, :debug)
DataMapper.setup(:default, "postgres://ruby:password@localhost/dm_test")
class User
include DataMapper::Resource
attr_accessor :password_confirmation
property :id, Serial
property :username, String
property :password, String
property :created_at, DateTime
property :updated_at, DateTime
has 1, :user_profile
end
class UserProfile
include DataMapper::Resource
property :id, Serial
property :email_address, String
property :display_name, String
property :bio, Text, :nullable => true
property :updated_at, DateTime
belongs_to :user
end
User.auto_migrate!
UserProfile.auto_migrate!
user = User.create(:username => "markbates", :password => "123456", :password_confirmation => "123456")
UserProfile.create(:user => User.first, :email_address => "mark@mackframework.com", :display_name => "Mark Bates", :bio => "asldfkjasdf")
puts "------"
puts user.user_profile.email_address
puts user.user_profile.display_name
puts user.user_profile.bio
Here is the Postgres log for this test:
2008-08-01 17:57:19.880 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 0.577 ms
2008-08-01 17:57:19.881 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.882 EDT 94533 0 ::1 dm_testLOG: 00000: statement: SELECT "id", "username", "password", "created_at", "updated_at" FROM "users" ORDER BY "id" LIMIT 1
2008-08-01 17:57:19.882 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:845
2008-08-01 17:57:19.882 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 0.267 ms
2008-08-01 17:57:19.882 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.893 EDT 94533 0 ::1 dm_testLOG: 00000: statement: SELECT "id", "email_address", "display_name", "updated_at", "user_id" FROM "user_profiles" WHERE "email_address" = 'mark@mackframework.com' ORDER BY "id" LIMIT 1
2008-08-01 17:57:19.893 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:845
2008-08-01 17:57:19.894 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 1.363 ms
2008-08-01 17:57:19.894 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.900 EDT 94533 0 ::1 dm_testLOG: 00000: statement: SELECT "id", "email_address", "display_name", "updated_at", "user_id" FROM "user_profiles" WHERE "email_address" = 'mark@mackframework.com' ORDER BY "id" LIMIT 1
2008-08-01 17:57:19.900 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:845
2008-08-01 17:57:19.901 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 0.432 ms
2008-08-01 17:57:19.901 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.904 EDT 94533 0 ::1 dm_testLOG: 00000: statement: INSERT INTO "user_profiles" ("email_address", "user_id", "updated_at", "bio", "display_name") VALUES ('mark@mackframework.com', 1, '2008-08-01T17:57:19-04:00', 'asldfkjasdf', 'Mark Bates') RETURNING "id"
2008-08-01 17:57:19.904 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:845
2008-08-01 17:57:19.905 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 1.118 ms
2008-08-01 17:57:19.905 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.913 EDT 94533 0 ::1 dm_testLOG: 00000: statement: SELECT COUNT(*) FROM "user_profiles"
2008-08-01 17:57:19.913 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:845
2008-08-01 17:57:19.913 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 0.862 ms
2008-08-01 17:57:19.913 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.915 EDT 94533 0 ::1 dm_testLOG: 00000: statement: SELECT "id", "email_address", "display_name", "updated_at", "user_id" FROM "user_profiles" WHERE "user_id" IN (1) ORDER BY "id"
2008-08-01 17:57:19.915 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:845
2008-08-01 17:57:19.916 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 0.456 ms
2008-08-01 17:57:19.916 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.918 EDT 94533 0 ::1 dm_testLOG: 00000: statement: SELECT "id", "email_address", "display_name", "updated_at", "user_id" FROM "user_profiles" WHERE "user_id" = 1 ORDER BY "id" LIMIT 1
2008-08-01 17:57:19.918 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:845
2008-08-01 17:57:19.918 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 0.338 ms
2008-08-01 17:57:19.918 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.927 EDT 94533 0 ::1 dm_testLOG: 00000: statement: SELECT "id", "email_address", "display_name", "updated_at", "user_id" FROM "user_profiles" WHERE "user_id" = 1 ORDER BY "id" LIMIT 1
2008-08-01 17:57:19.927 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:845
2008-08-01 17:57:19.927 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 2.557 ms
2008-08-01 17:57:19.927 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.929 EDT 94533 0 ::1 dm_testLOG: 00000: statement: SELECT "id", "email_address", "display_name", "updated_at", "user_id" FROM "user_profiles" WHERE "user_id" = 1 ORDER BY "id" LIMIT 1
2008-08-01 17:57:19.929 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:845
2008-08-01 17:57:19.929 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 0.334 ms
2008-08-01 17:57:19.929 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.940 EDT 94533 0 ::1 dm_testLOG: 00000: statement: SELECT "bio", "id" FROM "user_profiles" WHERE "user_id" IN (1) AND "id" IN (1) ORDER BY "id"
2008-08-01 17:57:19.940 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:845
2008-08-01 17:57:19.940 EDT 94533 0 ::1 dm_testLOG: 00000: duration: 0.551 ms
2008-08-01 17:57:19.940 EDT 94533 0 ::1 dm_testLOCATION: exec_simple_query, postgres.c:1056
2008-08-01 17:57:19.946 EDT 94533 0 ::1 dm_testLOG: 08P01: unexpected EOF on client connection
2008-08-01 17:57:19.946 EDT 94533 0 ::1 dm_testLOCATION: SocketBackend, postgres.c:323
As you can see it's hitting the DB multiple times at the end to first get the user_profile object, but then it makes separate calls back to the DB for the email_address and the display_name.
Comments and changes to this ticket
-
Sam Smoot August 1st, 2008 @ 05:09 PM
- Assigned user changed from Sam Smoot to Bernerd Schaefer
- State changed from new to open
- Tag changed from associations, dm-core to associations, bug, dm-core, priority
Hmm... a bug in PropertySet#defaults perhaps? We'll look into it. Thanks Mark.
-
Bernerd Schaefer August 4th, 2008 @ 12:44 PM
Can you update to edge (8149cf3) and let me know if this still happens? I just committed a fix that I think should resolve this (it resolved #505, which appears similar).
-
-
Bernerd Schaefer August 4th, 2008 @ 01:37 PM
- State changed from open to resolved
Thanks a bunch. I'll close this out — let us know if you come across anything else.
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
People watching this ticket
- Nobody is watching this ticket.