internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: rucio/rucio

Issue:
better handling NoSectionError in db/sqla/session
Motivation
----------
  File "/home/docs/checkouts/readthedocs.org/user_builds/rucio-blueprint/envs/latest/local/lib/python2.7/site-packages/rucio-1.14.8-py2.7.egg/rucio/db/sqla/session.py", line 51, in <module>
    DEFAULT_SCHEMA_NAME = config_get(DATABASE_SECTION, 'schema')
  File "/home/docs/checkouts/readthedocs.org/user_builds/rucio-blueprint/envs/latest/local/lib/python2.7/site-packages/rucio-1.14.8-py2.7.egg/rucio/common/config.py", line 32, in config_get
    return __CONFIG.get(section, option)
  File "/usr/lib/python2.7/ConfigParser.py", line 607, in get
    raise NoSectionError(section)
NoSectionError: No section: 'database'
Modification



Discussion:

Resolving patch:
diff --git a/lib/rucio/db/sqla/session.py b/lib/rucio/db/sqla/session.py
--- a/lib/rucio/db/sqla/session.py
+++ b/lib/rucio/db/sqla/session.py
@@ -150,10 +150,10 @@ def get_engine(echo=True):
                          ('pool_reset_on_return', str), ('use_threadlocal', int)]
         params = {}
         for param, param_type in config_params:
-            params[param] = param_type(config_get(DATABASE_SECTION,
-                                                  param,
-                                                  raise_exception=False,
-                                                  default=None))
+            try:
+                params[param] = param_type(config_get(DATABASE_SECTION, param))
+            except:
+                pass
         _ENGINE = create_engine(sql_connection, **params)
         if 'mysql' in sql_connection:
             event.listen(_ENGINE, 'checkout', mysql_ping_listener)


Test patch:
Repository: rucio/rucio

Issue:
Shuffle equal-weight protocols
If there are multiple equal-weight and otherwise-identical protocols, we should shuffle them when doing the selection.  This would prevent the same protocol from being selected over and over.

A use case we encountered for this is at NERSC, where they offer 9 identical GridFTP servers (all with different endpoints) to utilize as part of their RSE -- they consider load-balancing between the hosts to be part of the file transfer service's responsibility.
Shuffle equal-weight protocols
If there are multiple equal-weight and otherwise-identical protocols, we should shuffle them when doing the selection.  This would prevent the same protocol from being selected over and over.

A use case we encountered for this is at NERSC, where they offer 9 identical GridFTP servers (all with different endpoints) to utilize as part of their RSE -- they consider load-balancing between the hosts to be part of the file transfer service's responsibility.


Discussion:

Resolving patch:
diff --git a/lib/rucio/rse/rsemanager.py b/lib/rucio/rse/rsemanager.py
--- a/lib/rucio/rse/rsemanager.py
+++ b/lib/rucio/rse/rsemanager.py
@@ -19,6 +19,7 @@
 
 import copy
 import os
+import random
 
 from urlparse import urlparse
 
@@ -125,6 +126,8 @@ def select_protocol(rse_settings, operation, scheme=None, domain='wan'):
         raise exception.RSEProtocolDomainNotSupported('Domain %s not supported' % domain)
 
     candidates = _get_possible_protocols(rse_settings, operation, scheme, domain)
+    # Shuffle candidates to load-balance over equal sources
+    random.shuffle(candidates)
     return min(candidates, key=lambda k: k['domains'][domain][operation])
 
 
@@ -634,6 +637,10 @@ def find_matching_scheme(rse_settings_dest, rse_settings_src, operation_src, ope
     if not len(src_candidates) or not len(dest_candidates):
         raise exception.RSEProtocolNotSupported('No protocol for provided settings found : %s.' % str(rse_settings_dest))
 
+    # Shuffle the candidates to load-balance across equal weights.
+    random.shuffle(dest_candidates)
+    random.shuffle(src_candidates)
+
     # Select the one with the highest priority
     dest_candidates = sorted(dest_candidates, key=lambda k: k['domains'][domain][operation_dest])
     src_candidates = sorted(src_candidates, key=lambda k: k['domains'][domain][operation_src])


Test patch:
Repository: rucio/rucio

Issue:
Possibility to make a pip install directly from git url
Motivation
----------
To be able to install directly from master.


Discussion:
the openstack package pbr is nice for this and can be used (or at least as a source of inspiration)

cf. http://git.openstack.org/cgit/openstack-dev/pbr/tree/pbr/version.py



Implemented the following:
```
$ pip install git+git://github.com/vgaronne/rucio.git
$ rucio --version 
rucio 1.13.2-52-ge63dfb28-dev1519211244
```
The ge63dfb28-dev1519211244 is just based on the commit id? 
not completely. Have a look on the corresponding pull request.
Ah I see. Did you solve the issue with the installation of dependencies?
I didn't have a look on it. On next it is solved

Resolving patch:
diff --git a/doc/source/conf.py b/doc/source/conf.py
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -50,7 +50,7 @@
 
 # General information about the project.
 project = u'Rucio'
-copyright = u'2012-2018 CERN for the benefit of the ATLAS collaboration.'
+copyright = u'2012-2018 CERN for the benefit of the ATLAS collaboration'
 author = u'rucio-dev@cern.ch'
 
 # The version info for the project you're documenting, acts as replacement for
diff --git a/lib/rucio/common/doc/argparse/ext.py b/lib/rucio/common/doc/argparse/ext.py
--- a/lib/rucio/common/doc/argparse/ext.py
+++ b/lib/rucio/common/doc/argparse/ext.py
@@ -155,7 +155,7 @@ def print_subcommands(data, nested_content, markDownHelp=False):
     """
     Each subcommand is a dictionary with the following keys:
 
-    ['usage', 'action_groups', 'bare_usage', 'name', 'help']
+    ['usage', 'action_groups', 'bare_usage', 'name', 'help', 'epilog']
 
     In essence, this is all tossed in a new section with the title 'name'.
     Apparently there can also be a 'description' entry.
@@ -198,7 +198,12 @@ def print_subcommands(data, nested_content, markDownHelp=False):
             for x in print_subcommands(child, nested_content + subContent, markDownHelp):
                 sec += x
 
+            if 'epilog' in child and child['epilog']:
+                for element in renderList([child['epilog']], markDownHelp):
+                    sec += element
+
             subCommands += sec
+
         items.append(subCommands)
 
     return items
@@ -269,6 +274,7 @@ def _construct_manpage_specific_structure(self, parser_info):
             nested_parse_with_titles(
                 self.state, self.content, description_section)
             items.append(description_section)
+
         if parser_info.get('epilog') and 'noepilog' not in self.options:
             # TODO: do whatever sphinx does to understand ReST inside
             # docstrings magically imported from other places. The nested


Test patch:
Repository: rucio/rucio

Issue:
Update concepts & terminology section of the documentation
Motivation
----------
Update concepts & terminology section of the documentation

- [x] Rucio account
- [x] Files, Datasets and Containers
- [x] Rucio Storage Element
- [x] Meta-data attributes
- [x] Permission model
- [x] Replica management
- [x] Replication rule examples
- [x] RSE Expressions
- [x] Accounting and quota
- [x] Notifications
- [x] Subscriptions / Policies
documentation for Installing dev environment 
Motivation
----------

documentation for Installing dev environment 


Discussion:

Resolving patch:
diff --git a/lib/rucio/web/ui/common/utils.py b/lib/rucio/web/ui/common/utils.py
--- a/lib/rucio/web/ui/common/utils.py
+++ b/lib/rucio/web/ui/common/utils.py
@@ -6,7 +6,7 @@
 # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 #
 # Authors:
-# - Thomas Beermann, <thomas.beermann@cern.ch>, 2014-2017
+# - Thomas Beermann, <thomas.beermann@cern.ch>, 2014-2018
 
 from json import dumps
 from os.path import dirname, join
@@ -67,6 +67,9 @@ def check_token(rendered_tpl):
 
     dn = ctx.env.get('SSL_CLIENT_S_DN')
 
+    if not dn.startswith('/'):
+        dn = '/%s' % '/'.join(dn.split(',')[::-1])
+
     msg = "Your certificate (%s) is not mapped to any rucio account." % dn
     msg += "<br><br><font color=\"red\">First, please make sure it is correctly registered in <a href=\"https://voms2.cern.ch:8443/voms/atlas\">VOMS</a> and be patient until it has been fully propagated through the system.</font>"
     msg += "<br><br>Then, if it is still not working please contact <a href=\"mailto:atlas-adc-ddm-support@cern.ch\">DDM Support</a>."


Test patch:
Repository: rucio/rucio

Issue:
client dependencies update




Discussion:

Resolving patch:
diff --git a/setup_rucio_client.py b/setup_rucio_client.py
--- a/setup_rucio_client.py
+++ b/setup_rucio_client.py
@@ -1,15 +1,20 @@
-'''
- Copyright European Organization for Nuclear Research (CERN)
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  You may not use this file except in compliance with the License.
-  You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-  Authors:
-  - Vincent Garonne, <vincent.garonne@cern.ch>, 2011-2017
-  - Mario Lassnig, <mario.lassnig@cern.ch>, 2012-2013
-  - Martin Barisits, <martin.barisits@cern.ch>, 2016-2017
-'''
+# Copyright 2014-2018 CERN for the benefit of the ATLAS collaboration.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Authors:
+# - Vincent Garonne <vgaronne@gmail.com>, 2014-2018
+# - Martin Barisits <martin.barisits@cern.ch>, 2017
 
 import os
 import re
@@ -51,8 +56,10 @@
 
 SSH_EXTRAS = ['paramiko==1.18.4']
 KERBEROS_EXTRAS = ['kerberos>=1.2.5', 'pykerberos>=1.1.14', 'requests-kerberos>=0.11.0']
+SWIFT_EXTRAS = ['python-swiftclient>=3.5.0', ]
 EXTRAS_REQUIRES = dict(ssh=SSH_EXTRAS,
-                       kerberos=KERBEROS_EXTRAS)
+                       kerberos=KERBEROS_EXTRAS,
+                       swift=SWIFT_EXTRAS)
 
 if '--release' in COPY_ARGS:
     IS_RELEASE = True


Test patch:
Repository: rucio/rucio

Issue:
Flask imported in clients
Motivation
----------
Flask is being imported in lib.rucio.common.utils file, but it is not part of the pip-requires-clients file. This should be resolved (It should not be part of it)


Discussion:

Resolving patch:
diff --git a/lib/rucio/common/utils.py b/lib/rucio/common/utils.py
--- a/lib/rucio/common/utils.py
+++ b/lib/rucio/common/utils.py
@@ -1,17 +1,28 @@
-# Copyright European Organization for Nuclear Research (CERN)
+# Copyright 2012-2018 CERN for the benefit of the ATLAS collaboration.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
-# You may not use this file except in compliance with the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
 #
 # Authors:
-# - Vincent Garonne, <vincent.garonne@cern.ch>, 2012-2017
-# - Thomas Beermann, <thomas.beermann@cern.ch>, 2012, 2018
-# - Cedric Serfon, <cedric.serfon@cern.ch>, 2013-2017
-# - Martin Barisits, <martin.barisits@cern.ch>, 2017
-# - Mario Lassnig, <mario.lassnig@cern.ch>, 2017
+# - Vincent Garonne <vgaronne@gmail.com>, 2012-2018
+# - Thomas Beermann <thomas.beermann@cern.ch>, 2012-2018
+# - Mario Lassnig <mario.lassnig@cern.ch>, 2012-2017
+# - Cedric Serfon <cedric.serfon@cern.ch>, 2013-2017
+# - Ralph Vigne <ralph.vigne@cern.ch>, 2013
+# - Joaquin Bogado <jbogado@linti.unlp.edu.ar>, 2015
+# - Martin Barisits <martin.barisits@cern.ch>, 2016-2018
 # - Frank Berghaus, <frank.berghaus@cern.ch>, 2017
-# - Martin Barisits, <martin.barisits@cern.ch>, 2017-2018
+# - Brian Bockelman <bbockelm@cse.unl.edu>, 2018
+# - Tobias Wegner <twegner@cern.ch>, 2018
 
 import base64
 import datetime
@@ -28,7 +39,6 @@
 import subprocess
 import zlib
 
-from flask import Response
 from getpass import getuser
 from itertools import izip_longest
 from logging import getLogger, Formatter
@@ -42,7 +52,8 @@
 
 # Extra modules: Only imported if available
 EXTRA_MODULES = {'web': False,
-                 'paramiko': False}
+                 'paramiko': False,
+                 'flask': False}
 
 try:
     from rucio.db.sqla.enum import EnumSymbol
@@ -63,6 +74,9 @@
 if EXTRA_MODULES['paramiko']:
     from paramiko import RSAKey
 
+if EXTRA_MODULES['flask']:
+    from flask import Response
+
 # HTTP code dictionary. Not complete. Can be extended if needed.
 codes = {
     # Informational.


Test patch:
Repository: rucio/rucio

Issue:
Add Suggestions For MD5 Calculation
Motivation
----------
Mario suggested a patch when I added the MD5 sum calculation to the clients in #472 

Modification
------------
   - [x] add myself as author to the headers (and it's 2018, not 2017) :-)
   - [x] Sanitize variables (eg., adler32 checksum vs md5_digest)
      - rename: `checksum => a32_checksum`
      - rename: `md5_digest => md5_checksum`
      - _note_: in the DB the keys will stay `adler32` and `md5`
   - [x] test that the "hello test\n" md5sum is correctly reported



Discussion:

Resolving patch:
diff --git a/lib/rucio/rse/rsemanager.py b/lib/rucio/rse/rsemanager.py
--- a/lib/rucio/rse/rsemanager.py
+++ b/lib/rucio/rse/rsemanager.py
@@ -13,6 +13,7 @@
 # - Wen Guan, <wen.guan@cern.ch>, 2014-2015
 # - Martin Barisits, <martin.barisits@cern.ch>, 2017-2018
 # - Tobias Wegner, <tobias.wegner@cern.ch>, 2017
+# - Frank Berghaus, <frank.berghaus@cern.ch>, 2018
 
 
 import copy


Test patch:
diff --git a/lib/rucio/tests/test_bin_rucio.py b/lib/rucio/tests/test_bin_rucio.py
--- a/lib/rucio/tests/test_bin_rucio.py
+++ b/lib/rucio/tests/test_bin_rucio.py
@@ -14,6 +14,7 @@
   - Cheng-Hsi Chao, <cheng-hsi.chao@cern.ch>, 2014
   - Martin Barisits, <martin.barisits@cern.ch>, 2015
   - Cedric Serfon, <cedric.serfon@cern.ch>, 2015
+  - Frank Berghaus, <frank.berghaus@cern.ch>, 2018
 '''
 
 from os import remove, unlink, listdir, rmdir, stat
diff --git a/lib/rucio/tests/test_utils.py b/lib/rucio/tests/test_utils.py
--- a/lib/rucio/tests/test_utils.py
+++ b/lib/rucio/tests/test_utils.py
@@ -6,13 +6,13 @@
  http://www.apache.org/licenses/LICENSE-2.0
 
  Authors:
- - Frank Berghaus, <frank.berghaus@cern.ch>, 2017
+ - Frank Berghaus, <frank.berghaus@cern.ch>, 2018
 '''
 
 import unittest
 import tempfile
 
-from nose.tools import assert_is_instance, assert_is_not_none
+from nose.tools import assert_equal, assert_is_instance, assert_is_not_none
 from re import match
 from rucio.common.utils import md5
 
@@ -33,5 +33,7 @@ def tearDown(self):
     def test_utils_md5(self):
         """(COMMON/UTILS): test calculating MD5 of a file"""
         ret = md5(self.temp_file_1.name)
-        assert_is_instance(ret, str, msg="Object returned by tools.md5 is not a string")
-        assert_is_not_none(match('[a-fA-F0-9]{32}', ret), msg="String returned by tools.md5 is not a md5 hex digest")
+        assert_is_instance(ret, str, msg="Object returned by utils.md5 is not a string")
+        assert_is_not_none(match('[a-fA-F0-9]{32}', ret), msg="String returned by utils.md5 is not a md5 hex digest")
+        assert_equal(ret, '31d50dd6285b9ff9f8611d0762265d04',
+                     msg="Hex digest returned by utils.md5 is the MD5 checksum")
Repository: rucio/rucio

Issue:
RSE_Expressions link broken in documentation
Motivation
----------
Following the [RSE Expressions](http://rucio.readthedocs.io/RSE_Expressions.html) on http://rucio.readthedocs.io/overview_Rucio_Storage_Element.html leads to a non-existing page.

Modification
------------
Either the link in https://github.com/rucio/rucio/blob/master/doc/source/overview_Rucio_Storage_Element.rst needs to be made lower-case or the file https://github.com/rucio/rucio/blob/master/doc/source/rse_expressions.rst needs to be renamed to `RSE_Expressions`.


Discussion:

Resolving patch:
diff --git a/lib/rucio/client/downloadclient.py b/lib/rucio/client/downloadclient.py
--- a/lib/rucio/client/downloadclient.py
+++ b/lib/rucio/client/downloadclient.py
@@ -477,7 +477,7 @@ def send_trace(self, trace, trace_endpoint, user_agent, retries=5, threadnb=None
             else:
                 logger.debug('sending trace')
 
-        for dummy in xrange(retries):
+        for dummy in range(retries):
             try:
                 requests.post(trace_endpoint + '/traces/', verify=False, data=json.dumps(trace))
                 return 0


Test patch:
Repository: rucio/rucio

Issue:
RSE_Expressions link broken in documentation
Motivation
----------
Following the [RSE Expressions](http://rucio.readthedocs.io/RSE_Expressions.html) on http://rucio.readthedocs.io/overview_Rucio_Storage_Element.html leads to a non-existing page.

Modification
------------
Either the link in https://github.com/rucio/rucio/blob/master/doc/source/overview_Rucio_Storage_Element.rst needs to be made lower-case or the file https://github.com/rucio/rucio/blob/master/doc/source/rse_expressions.rst needs to be renamed to `RSE_Expressions`.


Discussion:

Resolving patch:
diff --git a/lib/rucio/common/utils.py b/lib/rucio/common/utils.py
--- a/lib/rucio/common/utils.py
+++ b/lib/rucio/common/utils.py
@@ -342,7 +342,7 @@ def chunks(l, n):
     """
     Yield successive n-sized chunks from l.
     """
-    for i in xrange(0, len(l), n):
+    for i in range(0, len(l), n):
         yield l[i:i + n]
 
 
@@ -675,7 +675,7 @@ def send_trace(trace, trace_endpoint, user_agent, retries=5, logger=None, log_pr
         logger.debug('%spilot detected - not sending trace' % log_prefix)
         return 0
     logger.debug('%ssending trace' % log_prefix)
-    for dummy in xrange(retries):
+    for dummy in range(retries):
         try:
             requests.post(trace_endpoint + '/traces/', verify=False, data=json.dumps(trace))
             return 0


Test patch:
Repository: rucio/rucio

Issue:
RSE_Expressions link broken in documentation
Motivation
----------
Following the [RSE Expressions](http://rucio.readthedocs.io/RSE_Expressions.html) on http://rucio.readthedocs.io/overview_Rucio_Storage_Element.html leads to a non-existing page.

Modification
------------
Either the link in https://github.com/rucio/rucio/blob/master/doc/source/overview_Rucio_Storage_Element.rst needs to be made lower-case or the file https://github.com/rucio/rucio/blob/master/doc/source/rse_expressions.rst needs to be renamed to `RSE_Expressions`.


Discussion:

Resolving patch:
diff --git a/lib/rucio/rse/protocols/webdav.py b/lib/rucio/rse/protocols/webdav.py
--- a/lib/rucio/rse/protocols/webdav.py
+++ b/lib/rucio/rse/protocols/webdav.py
@@ -308,7 +308,7 @@ def put(self, source, target, source_dir=None, progressbar=False):
                 raise exception.FileReplicaAlreadyExists()
             else:
                 # Create the directories before issuing the PUT
-                for directory_level in reversed(range(1, 4)):
+                for directory_level in reversed(list(range(1, 4))):
                     upper_directory = "/".join(directories[:-directory_level])
                     self.mkdir(upper_directory)
                 try:
@@ -358,7 +358,7 @@ def rename(self, pfn, new_pfn):
                 raise exception.SourceNotFound()
             else:
                 # Create the directories before issuing the MOVE
-                for directory_level in reversed(range(1, 4)):
+                for directory_level in reversed(list(range(1, 4))):
                     upper_directory = "/".join(directories[:-directory_level])
                     self.mkdir(upper_directory)
                 try:


Test patch:
Repository: rucio/rucio

Issue:
Add new unique index to oracle schema file
`CREATE UNIQUE INDEX ATLAS_RUCIO.QUARANTINED_REPLICAS_PATH_IDX on ATLAS_RUCIO.QUARANTINED_REPLICAS(PATH,RSE_ID) tablespace ATLAS_RUCIO_FACT_DATA01;
`


Discussion:
this should go also in alembic and schema

Resolving patch:
diff --git a/lib/rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py b/lib/rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py
new file mode 100644
--- /dev/null
+++ b/lib/rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py
@@ -0,0 +1,43 @@
+# Copyright 2013-2018 CERN for the benefit of the ATLAS collaboration.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Authors:
+# - Martin Barisits, <martin.barisits@cern.ch>, 2018
+#
+# Add index to quarantined replicas
+#
+# Revision ID: b818052fa670
+# Revises: 2962ece31cf4
+# Create Date: 2018-03-07 14:45:46.484383
+
+from alembic.op import (create_index, drop_index)
+
+
+# revision identifiers, used by Alembic.
+revision = 'b818052fa670'  # pylint: disable=invalid-name
+down_revision = '2962ece31cf4'  # pylint: disable=invalid-name
+
+
+def upgrade():
+    '''
+    upgrade method
+    '''
+    create_index('QUARANTINED_REPLICAS_PATH_IDX', 'quarantined_replicas', ['path', 'rse_id'], unique=True)
+
+
+def downgrade():
+    '''
+    downgrade method
+    '''
+    drop_index('QUARANTINED_REPLICAS_PATH_IDX', 'quarantined_replicas')
diff --git a/lib/rucio/db/sqla/models.py b/lib/rucio/db/sqla/models.py
--- a/lib/rucio/db/sqla/models.py
+++ b/lib/rucio/db/sqla/models.py
@@ -11,7 +11,7 @@
   - Angelos Molfetas, <angelos.molfetas@cern.ch>, 2012
   - Ralph Vigne, <ralph.vigne@cern.ch>, 2013
   - Cedric Serfon, <cedric.serfon@cern.ch>, 2013-2018
-  - Martin Barisits, <martin.barisits@cern.ch>, 2013-2015
+  - Martin Barisits, <martin.barisits@cern.ch>, 2013-2018
   - Wen Guan, <wen.guan@cern.ch>, 2015
 
 SQLAlchemy models for rucio data
@@ -456,7 +456,8 @@ class QuarantinedReplica(BASE, ModelBase, Versioned):
     scope = Column(String(SCOPE_LENGTH))
     name = Column(String(NAME_LENGTH))
     _table_args = (PrimaryKeyConstraint('rse_id', 'path', name='QURD_REPLICAS_STATE_PK'),
-                   ForeignKeyConstraint(['rse_id'], ['rses.id'], name='QURD_REPLICAS_RSE_ID_FK'))
+                   ForeignKeyConstraint(['rse_id'], ['rses.id'], name='QURD_REPLICAS_RSE_ID_FK'),
+                   Index('QUARANTINED_REPLICAS_PATH_IDX', 'path', 'rse_id', unique=True))
 
 
 class DIDKey(BASE, ModelBase):


Test patch: