##// END OF EJS Templates
typos+docs.
marcink -
r2769:52617fb7 beta
parent child Browse files
Show More
@@ -1,402 +1,404 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.pullrequests
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 pull requests controller for rhodecode for initializing pull requests
7 7
8 8 :created_on: May 7, 2012
9 9 :author: marcink
10 10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software: you can redistribute it and/or modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25 import logging
26 26 import traceback
27 27 import formencode
28 28
29 29 from webob.exc import HTTPNotFound, HTTPForbidden
30 30 from collections import defaultdict
31 31 from itertools import groupby
32 32
33 33 from pylons import request, response, session, tmpl_context as c, url
34 34 from pylons.controllers.util import abort, redirect
35 35 from pylons.i18n.translation import _
36 36 from pylons.decorators import jsonify
37 37
38 38 from rhodecode.lib.compat import json
39 39 from rhodecode.lib.base import BaseRepoController, render
40 40 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator,\
41 41 NotAnonymous
42 42 from rhodecode.lib import helpers as h
43 43 from rhodecode.lib import diffs
44 44 from rhodecode.lib.utils import action_logger
45 45 from rhodecode.model.db import User, PullRequest, ChangesetStatus,\
46 46 ChangesetComment
47 47 from rhodecode.model.pull_request import PullRequestModel
48 48 from rhodecode.model.meta import Session
49 49 from rhodecode.model.repo import RepoModel
50 50 from rhodecode.model.comment import ChangesetCommentsModel
51 51 from rhodecode.model.changeset_status import ChangesetStatusModel
52 52 from rhodecode.model.forms import PullRequestForm
53 53
54 54 log = logging.getLogger(__name__)
55 55
56 56
57 57 class PullrequestsController(BaseRepoController):
58 58
59 59 @LoginRequired()
60 60 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
61 61 'repository.admin')
62 62 def __before__(self):
63 63 super(PullrequestsController, self).__before__()
64 64 repo_model = RepoModel()
65 65 c.users_array = repo_model.get_users_js()
66 66 c.users_groups_array = repo_model.get_users_groups_js()
67 67
68 68 def _get_repo_refs(self, repo):
69 69 hist_l = []
70 70
71 71 branches_group = ([('branch:%s:%s' % (k, v), k) for
72 72 k, v in repo.branches.iteritems()], _("Branches"))
73 73 bookmarks_group = ([('book:%s:%s' % (k, v), k) for
74 74 k, v in repo.bookmarks.iteritems()], _("Bookmarks"))
75 75 tags_group = ([('tag:%s:%s' % (k, v), k) for
76 76 k, v in repo.tags.iteritems()], _("Tags"))
77 77
78 78 hist_l.append(bookmarks_group)
79 79 hist_l.append(branches_group)
80 80 hist_l.append(tags_group)
81 81
82 82 return hist_l
83 83
84 84 def show_all(self, repo_name):
85 85 c.pull_requests = PullRequestModel().get_all(repo_name)
86 86 c.repo_name = repo_name
87 87 return render('/pullrequests/pullrequest_show_all.html')
88 88
89 89 @NotAnonymous()
90 90 def index(self):
91 91 org_repo = c.rhodecode_db_repo
92 92
93 93 if org_repo.scm_instance.alias != 'hg':
94 94 log.error('Review not available for GIT REPOS')
95 95 raise HTTPNotFound
96 96
97 97 other_repos_info = {}
98 98
99 99 c.org_refs = self._get_repo_refs(c.rhodecode_repo)
100 100 c.org_repos = []
101 101 c.other_repos = []
102 102 c.org_repos.append((org_repo.repo_name, '%s/%s' % (
103 103 org_repo.user.username, c.repo_name))
104 104 )
105 105
106 106 # add org repo to other so we can open pull request agains itself
107 107 c.other_repos.extend(c.org_repos)
108 108
109 109 c.default_pull_request = org_repo.repo_name
110 110 c.default_revs = self._get_repo_refs(org_repo.scm_instance)
111 111 #add orginal repo
112 112 other_repos_info[org_repo.repo_name] = {
113 113 'gravatar': h.gravatar_url(org_repo.user.email, 24),
114 114 'description': org_repo.description,
115 115 'revs': h.select('other_ref', '', c.default_revs, class_='refs')
116 116 }
117 117
118 118 #gather forks and add to this list
119 119 for fork in org_repo.forks:
120 120 c.other_repos.append((fork.repo_name, '%s/%s' % (
121 121 fork.user.username, fork.repo_name))
122 122 )
123 123 other_repos_info[fork.repo_name] = {
124 124 'gravatar': h.gravatar_url(fork.user.email, 24),
125 125 'description': fork.description,
126 126 'revs': h.select('other_ref', '',
127 127 self._get_repo_refs(fork.scm_instance),
128 128 class_='refs')
129 129 }
130 130 #add parents of this fork also
131 131 if org_repo.parent:
132 132 c.default_pull_request = org_repo.parent.repo_name
133 133 c.other_repos.append((org_repo.parent.repo_name, '%s/%s' % (
134 134 org_repo.parent.user.username,
135 135 org_repo.parent.repo_name))
136 136 )
137 137 other_repos_info[org_repo.parent.repo_name] = {
138 138 'gravatar': h.gravatar_url(org_repo.parent.user.email, 24),
139 139 'description': org_repo.parent.description,
140 140 'revs': h.select('other_ref', '',
141 141 self._get_repo_refs(org_repo.parent.scm_instance),
142 142 class_='refs')
143 143 }
144 144
145 145 c.other_repos_info = json.dumps(other_repos_info)
146 146 c.review_members = [org_repo.user]
147 147 return render('/pullrequests/pullrequest.html')
148 148
149 149 @NotAnonymous()
150 150 def create(self, repo_name):
151 151 try:
152 152 _form = PullRequestForm()().to_python(request.POST)
153 153 except formencode.Invalid, errors:
154 154 log.error(traceback.format_exc())
155 155 if errors.error_dict.get('revisions'):
156 156 msg = 'Revisions: %s' % errors.error_dict['revisions']
157 157 elif errors.error_dict.get('pullrequest_title'):
158 158 msg = _('Pull request requires a title with min. 3 chars')
159 159 else:
160 160 msg = _('error during creation of pull request')
161 161
162 162 h.flash(msg, 'error')
163 163 return redirect(url('pullrequest_home', repo_name=repo_name))
164 164
165 165 org_repo = _form['org_repo']
166 166 org_ref = _form['org_ref']
167 167 other_repo = _form['other_repo']
168 168 other_ref = _form['other_ref']
169 169 revisions = _form['revisions']
170 170 reviewers = _form['review_members']
171 171
172 172 title = _form['pullrequest_title']
173 173 description = _form['pullrequest_desc']
174 174
175 175 try:
176 176 pull_request = PullRequestModel().create(
177 177 self.rhodecode_user.user_id, org_repo, org_ref, other_repo,
178 178 other_ref, revisions, reviewers, title, description
179 179 )
180 180 Session().commit()
181 181 h.flash(_('Successfully opened new pull request'),
182 182 category='success')
183 183 except Exception:
184 184 h.flash(_('Error occurred during sending pull request'),
185 185 category='error')
186 186 log.error(traceback.format_exc())
187 187 return redirect(url('pullrequest_home', repo_name=repo_name))
188 188
189 189 return redirect(url('pullrequest_show', repo_name=other_repo,
190 190 pull_request_id=pull_request.pull_request_id))
191 191
192 192 @NotAnonymous()
193 193 @jsonify
194 194 def update(self, repo_name, pull_request_id):
195 195 pull_request = PullRequest.get_or_404(pull_request_id)
196 196 if pull_request.is_closed():
197 197 raise HTTPForbidden()
198
198 #only owner or admin can update it
199 owner = pull_request.author.user_id == c.rhodecode_user.user_id
200 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
199 201 reviewers_ids = map(int, filter(lambda v: v not in [None, ''],
200 202 request.POST.get('reviewers_ids', '').split(',')))
201 203
202 204 PullRequestModel().update_reviewers(pull_request_id, reviewers_ids)
203 205 Session.commit()
204 206 return True
207 raise HTTPForbidden()
205 208
206 209 @NotAnonymous()
207 210 @jsonify
208 211 def delete(self, repo_name, pull_request_id):
209 212 pull_request = PullRequest.get_or_404(pull_request_id)
210 213 #only owner can delete it !
211 214 if pull_request.author.user_id == c.rhodecode_user.user_id:
212 215 PullRequestModel().delete(pull_request)
213 216 Session().commit()
214 217 h.flash(_('Successfully deleted pull request'),
215 218 category='success')
216 219 return redirect(url('admin_settings_my_account'))
217 else:
218 220 raise HTTPForbidden()
219 221
220 222 def _load_compare_data(self, pull_request, enable_comments=True):
221 223 """
222 224 Load context data needed for generating compare diff
223 225
224 226 :param pull_request:
225 227 :type pull_request:
226 228 """
227 229
228 230 org_repo = pull_request.org_repo
229 231 (org_ref_type,
230 232 org_ref_name,
231 233 org_ref_rev) = pull_request.org_ref.split(':')
232 234
233 235 other_repo = pull_request.other_repo
234 236 (other_ref_type,
235 237 other_ref_name,
236 238 other_ref_rev) = pull_request.other_ref.split(':')
237 239
238 240 # despite opening revisions for bookmarks/branches/tags, we always
239 241 # convert this to rev to prevent changes after book or branch change
240 242 org_ref = ('rev', org_ref_rev)
241 243 other_ref = ('rev', other_ref_rev)
242 244
243 245 c.org_repo = org_repo
244 246 c.other_repo = other_repo
245 247
246 248 c.cs_ranges, discovery_data = PullRequestModel().get_compare_data(
247 249 org_repo, org_ref, other_repo, other_ref
248 250 )
249 251
250 252 c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
251 253 c.cs_ranges])
252 254 # defines that we need hidden inputs with changesets
253 255 c.as_form = request.GET.get('as_form', False)
254 256
255 257 c.org_ref = org_ref[1]
256 258 c.other_ref = other_ref[1]
257 259 # diff needs to have swapped org with other to generate proper diff
258 260 _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref,
259 261 discovery_data)
260 262 diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
261 263 _parsed = diff_processor.prepare()
262 264
263 265 c.files = []
264 266 c.changes = {}
265 267
266 268 for f in _parsed:
267 269 fid = h.FID('', f['filename'])
268 270 c.files.append([fid, f['operation'], f['filename'], f['stats']])
269 271 diff = diff_processor.as_html(enable_comments=enable_comments,
270 272 diff_lines=[f])
271 273 c.changes[fid] = [f['operation'], f['filename'], diff]
272 274
273 275 def show(self, repo_name, pull_request_id):
274 276 repo_model = RepoModel()
275 277 c.users_array = repo_model.get_users_js()
276 278 c.users_groups_array = repo_model.get_users_groups_js()
277 279 c.pull_request = PullRequest.get_or_404(pull_request_id)
278 280
279 281 cc_model = ChangesetCommentsModel()
280 282 cs_model = ChangesetStatusModel()
281 283 _cs_statuses = cs_model.get_statuses(c.pull_request.org_repo,
282 284 pull_request=c.pull_request,
283 285 with_revisions=True)
284 286
285 287 cs_statuses = defaultdict(list)
286 288 for st in _cs_statuses:
287 289 cs_statuses[st.author.username] += [st]
288 290
289 291 c.pull_request_reviewers = []
290 292 c.pull_request_pending_reviewers = []
291 293 for o in c.pull_request.reviewers:
292 294 st = cs_statuses.get(o.user.username, None)
293 295 if st:
294 296 sorter = lambda k: k.version
295 297 st = [(x, list(y)[0])
296 298 for x, y in (groupby(sorted(st, key=sorter), sorter))]
297 299 else:
298 300 c.pull_request_pending_reviewers.append(o.user)
299 301 c.pull_request_reviewers.append([o.user, st])
300 302
301 303 # pull_requests repo_name we opened it against
302 304 # ie. other_repo must match
303 305 if repo_name != c.pull_request.other_repo.repo_name:
304 306 raise HTTPNotFound
305 307
306 308 # load compare data into template context
307 309 enable_comments = not c.pull_request.is_closed()
308 310 self._load_compare_data(c.pull_request, enable_comments=enable_comments)
309 311
310 312 # inline comments
311 313 c.inline_cnt = 0
312 314 c.inline_comments = cc_model.get_inline_comments(
313 315 c.rhodecode_db_repo.repo_id,
314 316 pull_request=pull_request_id)
315 317 # count inline comments
316 318 for __, lines in c.inline_comments:
317 319 for comments in lines.values():
318 320 c.inline_cnt += len(comments)
319 321 # comments
320 322 c.comments = cc_model.get_comments(c.rhodecode_db_repo.repo_id,
321 323 pull_request=pull_request_id)
322 324
323 325 # changeset(pull-request) status
324 326 c.current_changeset_status = cs_model.calculate_status(
325 327 c.pull_request_reviewers
326 328 )
327 329 c.changeset_statuses = ChangesetStatus.STATUSES
328 330 c.target_repo = c.pull_request.org_repo.repo_name
329 331 return render('/pullrequests/pullrequest_show.html')
330 332
331 333 @NotAnonymous()
332 334 @jsonify
333 335 def comment(self, repo_name, pull_request_id):
334 336 pull_request = PullRequest.get_or_404(pull_request_id)
335 337 if pull_request.is_closed():
336 338 raise HTTPForbidden()
337 339
338 340 status = request.POST.get('changeset_status')
339 341 change_status = request.POST.get('change_changeset_status')
340 342
341 343 comm = ChangesetCommentsModel().create(
342 344 text=request.POST.get('text'),
343 345 repo=c.rhodecode_db_repo.repo_id,
344 346 user=c.rhodecode_user.user_id,
345 347 pull_request=pull_request_id,
346 348 f_path=request.POST.get('f_path'),
347 349 line_no=request.POST.get('line'),
348 350 status_change=(ChangesetStatus.get_status_lbl(status)
349 351 if status and change_status else None)
350 352 )
351 353
352 354 # get status if set !
353 355 if status and change_status:
354 356 ChangesetStatusModel().set_status(
355 357 c.rhodecode_db_repo.repo_id,
356 358 status,
357 359 c.rhodecode_user.user_id,
358 360 comm,
359 361 pull_request=pull_request_id
360 362 )
361 363 action_logger(self.rhodecode_user,
362 364 'user_commented_pull_request:%s' % pull_request_id,
363 365 c.rhodecode_db_repo, self.ip_addr, self.sa)
364 366
365 367 if request.POST.get('save_close'):
366 368 PullRequestModel().close_pull_request(pull_request_id)
367 369 action_logger(self.rhodecode_user,
368 370 'user_closed_pull_request:%s' % pull_request_id,
369 371 c.rhodecode_db_repo, self.ip_addr, self.sa)
370 372
371 373 Session().commit()
372 374
373 375 if not request.environ.get('HTTP_X_PARTIAL_XHR'):
374 376 return redirect(h.url('pullrequest_show', repo_name=repo_name,
375 377 pull_request_id=pull_request_id))
376 378
377 379 data = {
378 380 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
379 381 }
380 382 if comm:
381 383 c.co = comm
382 384 data.update(comm.get_dict())
383 385 data.update({'rendered_text':
384 386 render('changeset/changeset_comment_block.html')})
385 387
386 388 return data
387 389
388 390 @NotAnonymous()
389 391 @jsonify
390 392 def delete_comment(self, repo_name, comment_id):
391 393 co = ChangesetComment.get(comment_id)
392 394 if co.pull_request.is_closed():
393 395 #don't allow deleting comments on closed pull request
394 396 raise HTTPForbidden()
395 397
396 398 owner = lambda: co.author.user_id == c.rhodecode_user.user_id
397 399 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
398 400 ChangesetCommentsModel().delete(comment=co)
399 401 Session().commit()
400 402 return True
401 403 else:
402 404 raise HTTPForbidden()
@@ -1,173 +1,186 b''
1 1 import logging
2 2 import datetime
3 3
4 4 from sqlalchemy import *
5 5 from sqlalchemy.exc import DatabaseError
6 6 from sqlalchemy.orm import relation, backref, class_mapper
7 7 from sqlalchemy.orm.session import Session
8 8 from sqlalchemy.ext.declarative import declarative_base
9 9
10 10 from rhodecode.lib.dbmigrate.migrate import *
11 11 from rhodecode.lib.dbmigrate.migrate.changeset import *
12 12
13 13 from rhodecode.model.meta import Base
14 14 from rhodecode.model import meta
15 15
16 16 log = logging.getLogger(__name__)
17 17
18 18
19 19 def upgrade(migrate_engine):
20 20 """
21 21 Upgrade operations go here.
22 22 Don't create your own engine; bind migrate_engine to your metadata
23 23 """
24 24
25 25 #==========================================================================
26 26 # USEREMAILMAP
27 27 #==========================================================================
28 28 from rhodecode.lib.dbmigrate.schema.db_1_4_0 import UserEmailMap
29 29 tbl = UserEmailMap.__table__
30 30 tbl.create()
31 31 #==========================================================================
32 32 # PULL REQUEST
33 33 #==========================================================================
34 34 from rhodecode.lib.dbmigrate.schema.db_1_4_0 import PullRequest
35 35 tbl = PullRequest.__table__
36 36 tbl.create()
37 37
38 38 #==========================================================================
39 39 # PULL REQUEST REVIEWERS
40 40 #==========================================================================
41 41 from rhodecode.lib.dbmigrate.schema.db_1_4_0 import PullRequestReviewers
42 42 tbl = PullRequestReviewers.__table__
43 43 tbl.create()
44 44
45 45 #==========================================================================
46 46 # CHANGESET STATUS
47 47 #==========================================================================
48 48 from rhodecode.lib.dbmigrate.schema.db_1_4_0 import ChangesetStatus
49 49 tbl = ChangesetStatus.__table__
50 50 tbl.create()
51 51
52 52 ## RESET COMPLETLY THE metadata for sqlalchemy to use the 1_3_0 Base
53 53 Base = declarative_base()
54 54 Base.metadata.clear()
55 55 Base.metadata = MetaData()
56 56 Base.metadata.bind = migrate_engine
57 57 meta.Base = Base
58 58
59 59 #==========================================================================
60 60 # USERS TABLE
61 61 #==========================================================================
62 62 from rhodecode.lib.dbmigrate.schema.db_1_3_0 import User
63 63 tbl = User.__table__
64 64
65 65 # change column name -> firstname
66 66 col = User.__table__.columns.name
67 67 col.alter(index=Index('u_username_idx', 'username'))
68 68 col.alter(index=Index('u_email_idx', 'email'))
69 69 col.alter(name="firstname", table=tbl)
70 70
71 inherit_default_permissions = Column("users_group_inherit_default_permission",
72 Boolean(), nullable=True, unique=None,
73 default=True)
74 inherit_default_permissions.create(table=tbl)
75 inherit_default_permissions.alter(nullable=False, default=True, table=tbl)
76
77 #==========================================================================
78 # GROUPS TABLE
79 #==========================================================================
80 from rhodecode.lib.dbmigrate.schema.db_1_3_0 import RepoGroup
81 tbl = RepoGroup.__table__
71 # add inherit_default_permission column
82 72 inherit_default_permissions = Column("inherit_default_permissions",
83 73 Boolean(), nullable=True, unique=None,
84 74 default=True)
85 75 inherit_default_permissions.create(table=tbl)
86 76 inherit_default_permissions.alter(nullable=False, default=True, table=tbl)
87 77
88 78 #==========================================================================
79 # USERS GROUP TABLE
80 #==========================================================================
81 from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UsersGroup
82 tbl = UsersGroup.__table__
83 # add inherit_default_permission column
84 gr_inherit_default_permissions = Column(
85 "users_group_inherit_default_permissions",
86 Boolean(), nullable=True, unique=None,
87 default=True)
88 gr_inherit_default_permissions.create(table=tbl)
89 gr_inherit_default_permissions.alter(nullable=False, default=True, table=tbl)
90
91 #==========================================================================
89 92 # REPOSITORIES
90 93 #==========================================================================
91 94 from rhodecode.lib.dbmigrate.schema.db_1_3_0 import Repository
92 95 tbl = Repository.__table__
93 96
97 # add enable locking column
94 98 enable_locking = Column("enable_locking", Boolean(), nullable=True,
95 99 unique=None, default=False)
96 100 enable_locking.create(table=tbl)
97 101 enable_locking.alter(nullable=False, default=False, table=tbl)
98 102
103 # add locked column
99 104 _locked = Column("locked", String(255), nullable=True, unique=False,
100 105 default=None)
101 106 _locked.create(table=tbl)
102 107
108 #add langing revision column
103 109 landing_rev = Column("landing_revision", String(255), nullable=True,
104 110 unique=False, default='tip')
105 111 landing_rev.create(table=tbl)
106 112 landing_rev.alter(nullable=False, default='tip', table=tbl)
107 113
108 114 #==========================================================================
109 115 # GROUPS
110 116 #==========================================================================
111 117 from rhodecode.lib.dbmigrate.schema.db_1_3_0 import RepoGroup
112 118 tbl = RepoGroup.__table__
119
120 # add enable locking column
113 121 enable_locking = Column("enable_locking", Boolean(), nullable=True,
114 122 unique=None, default=False)
115 123 enable_locking.create(table=tbl)
116 124 enable_locking.alter(nullable=False, default=False)
117 125
118 126 #==========================================================================
119 127 # CACHE INVALIDATION
120 128 #==========================================================================
121 129 from rhodecode.lib.dbmigrate.schema.db_1_3_0 import CacheInvalidation
122 130 tbl = CacheInvalidation.__table__
123 131
124 # change column name -> firstname
132 # add INDEX for cache keys
125 133 col = CacheInvalidation.__table__.columns.cache_key
126 134 col.alter(index=Index('key_idx', 'cache_key'))
127 135
128 136 #==========================================================================
129 137 # NOTIFICATION
130 138 #==========================================================================
131 139 from rhodecode.lib.dbmigrate.schema.db_1_3_0 import Notification
132 140 tbl = Notification.__table__
133 141
134 # change column name -> firstname
142 # add index for notification type
135 143 col = Notification.__table__.columns.type
136 144 col.alter(index=Index('notification_type_idx', 'type'),)
137 145
138 146 #==========================================================================
139 147 # CHANGESET_COMMENTS
140 148 #==========================================================================
141 149 from rhodecode.lib.dbmigrate.schema.db_1_3_0 import ChangesetComment
142 150
143 151 tbl = ChangesetComment.__table__
152 col = ChangesetComment.__table__.columns.revision
144 153
145 col = ChangesetComment.__table__.columns.revision
154 # add index for revisions
146 155 col.alter(index=Index('cc_revision_idx', 'revision'),)
147 156
157 # add hl_lines column
148 158 hl_lines = Column('hl_lines', Unicode(512), nullable=True)
149 159 hl_lines.create(table=tbl)
150 160
161 # add created_on column
151 162 created_on = Column('created_on', DateTime(timezone=False), nullable=True,
152 163 default=datetime.datetime.now)
153 164 created_on.create(table=tbl)
154 165 created_on.alter(nullable=False, default=datetime.datetime.now)
166
155 167 modified_at = Column('modified_at', DateTime(timezone=False), nullable=False,
156 168 default=datetime.datetime.now)
157 169 modified_at.alter(type=DateTime(timezone=False), table=tbl)
158 170
171 # add FK to pull_request
159 172 pull_request_id = Column("pull_request_id", Integer(),
160 173 ForeignKey('pull_requests.pull_request_id'),
161 174 nullable=True)
162 175 pull_request_id.create(table=tbl)
163 176 ## RESET COMPLETLY THE metadata for sqlalchemy back after using 1_3_0
164 177 Base = declarative_base()
165 178 Base.metadata.clear()
166 179 Base.metadata = MetaData()
167 180 Base.metadata.bind = migrate_engine
168 181 meta.Base = Base
169 182
170 183
171 184 def downgrade(migrate_engine):
172 185 meta = MetaData()
173 186 meta.bind = migrate_engine
General Comments 0
You need to be logged in to leave comments. Login now