Multiple retired users with same name prevent import/export of db.

"John P. Rouillard" <[email protected]>
Newsgroups gmane.comp.bug-tracking.roundup.devel
Message-ID <[email protected]>
Hi all:

The darcs folks are trying to upgrade to 2.0.0 and change their
backend database from postgres to sqlite.

Trying to import an export they get:

   IntegrityError: UNIQUE constraint failed: _user.__retired__, _user._username

They have multiple retired users with the same username.

I think there is info lost on export cycle.  In my sqlite test the
database multiple retired users with the same name show up as:

  select id, _username, __retired__ from _user order by id;
  1|admin|0
  ...
  22|duplicate|22
  23|duplicate|23
24|duplicate|0

So it looks like __retired__ is not a boolean but 0 if not retired and
the id if retired. (sql defining the field is: __retired__ INTEGER
DEFAULT 0). However when exported, the corresponding output looks
like:

  activity:actor:address:...:id:...:username:is retired

  (2021, 6, 5, 22, 17, 28.615, 0, 0, 0):'1':'[email protected]':...'22':...:'duplicate':True

  (2021, 6, 5, 22, 20, 5.85, 0, 0, 0):'1':'[email protected]':...:'24':...:'duplicate':False

so you only get True/False for retired, not the integer number in the
original database.

I suggested to the darcs folks that munging the username of the
retired users is probably the easiest thing to do.

But how do we fix thing for the future? I think having multiple users
with the same username who are retired is probably an edge case. (I
would certainly find it confusing). But we should handle this better.

I see two main ways to do it:

1. change export format and print 'is retired' as an integer to
   match the database. Then import it as the integer it is.


2. change the import function to take an 'is retired' True value
   and insert the user id into the __retired__ index.

   Current if retired is true, it runs:

     update _user set __retired__=%s where id=%s'

   where %s is self.db.arg. But I have no idea what self.db.arg is in
   this context or why the id (actually newid defined earlier in the
   code) isn't used. There is a comment:

        if retire:
            # use the arg for __retired__ to cope with any odd database type
            # conversion (hello, sqlite)
            sql = 'update _%s set __retired__=%s where id=%s'%(self.classname,
                self.db.arg, self.db.arg)
            self.db.sql(sql, (newid, newid))

    No idea what this means. Ralf any ideas here?

I am leaning toward #2 but....

Code above is in import_list in backend/rdbms_common.py.

Anybody have a preference? Can shine any light on this?

Thanks.

--
				-- rouilj
John Rouillard
===========================================================================
My employers don't acknowledge my existence much less my opinions.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.